|
| 1 | +module QuantileRegression |
| 2 | + |
| 3 | +export quantileregression |
| 4 | + |
| 5 | +using JuMP |
| 6 | +using GLPK |
| 7 | + |
| 8 | +import ..Basis: |
| 9 | + RegressionSetting, @extractRegressionSetting, designMatrix, responseVector, applyColumns |
| 10 | + |
| 11 | +""" |
| 12 | +
|
| 13 | + quantileregression(setting; tau = 0.5) |
| 14 | +
|
| 15 | +Perform Quantile Regression for a given regression setting (multiple linear regression). |
| 16 | +
|
| 17 | +# Arguments |
| 18 | +- `setting::RegressionSetting`: RegressionSetting object with a formula and dataset. |
| 19 | +- `tau::Float64`: Quantile level. Default is 0.5. |
| 20 | +
|
| 21 | +# Description |
| 22 | +The Quantile Regression estimator searches for the regression parameter estimates that minimize the |
| 23 | + |
| 24 | +
|
| 25 | +Min z = (1 - tau) (u1(-) + u2(-) + ... + un(-)) + tau (u1(+) + u2(+) + ... + un(+)) |
| 26 | +Subject to: |
| 27 | + y_1 - beta0 - beta1 * x_2 + u1(-) - u1(+) = 0 |
| 28 | + y_2 - beta0 - beta1 * x_2 + u2(-) - u2(+) = 0 |
| 29 | + . |
| 30 | + . |
| 31 | + . |
| 32 | + y_n - beta0 - beta1 * x_n + un(-) - un(+) = 0 |
| 33 | +where |
| 34 | + ui(-), ui(+) >= 0 |
| 35 | + i = 1, 2, ..., n |
| 36 | + beta0, beta1 in R |
| 37 | + n : Number of observations |
| 38 | + model is the y = beta1 + beta2 * x + u |
| 39 | +
|
| 40 | +# Output |
| 41 | +- `["betas"]`: Estimated regression coefficients |
| 42 | +- `["residuals"]`: Regression residuals |
| 43 | +- `["model"]`: Linear Programming Model |
| 44 | +
|
| 45 | +# Examples |
| 46 | +```julia-repl |
| 47 | +julia> reg0001 = createRegressionSetting(@formula(calls ~ year), phones); |
| 48 | +julia> quantileregression(reg0001) |
| 49 | +``` |
| 50 | +
|
| 51 | +""" |
| 52 | +function quantileregression(setting::RegressionSetting; tau::Float64 = 0.5) |
| 53 | + X, y = @extractRegressionSetting setting |
| 54 | + return quantileregression(X, y, tau = tau) |
| 55 | +end |
| 56 | + |
| 57 | + |
| 58 | +""" |
| 59 | +
|
| 60 | + quantileregression(X, y, tau = 0.5) |
| 61 | +
|
| 62 | +Estimates parameters of linear regression using Quantile Regression Estimator for a given regression setting. |
| 63 | +
|
| 64 | +# Arguments |
| 65 | +- `X::Array{Float64, 2}`: Design matrix of the linear model. |
| 66 | +- `y::Array{Float64, 1}`: Response vector of the linear model. |
| 67 | +- `tau::Float64`: Quantile level. Default is 0.5. |
| 68 | +
|
| 69 | +
|
| 70 | +# Examples |
| 71 | +```julia-repl |
| 72 | +julia> income = [420.157651, 541.411707, 901.157457, 639.080229, 750.875606]; |
| 73 | +julia> foodexp = [255.839425, 310.958667, 485.680014, 402.997356, 495.560775]; |
| 74 | +
|
| 75 | +julia> n = length(income) |
| 76 | +julia> X = hcat(ones(Float64, n), income) |
| 77 | +
|
| 78 | +julia> result = quantileregression(X, foodexp, tau = 0.25) |
| 79 | +``` |
| 80 | +
|
| 81 | +
|
| 82 | +""" |
| 83 | +function quantileregression(X::Array{Float64,2}, y::Array{Float64,1}; tau::Float64 = 0.5) |
| 84 | + n, p = size(X) |
| 85 | + |
| 86 | + m = JuMP.Model(GLPK.Optimizer) |
| 87 | + |
| 88 | + JuMP.@variable(m, d[1:(2n)]) |
| 89 | + JuMP.@variable(m, beta[1:p]) |
| 90 | + |
| 91 | + JuMP.@objective( |
| 92 | + m, |
| 93 | + Min, |
| 94 | + sum((1 - tau) * d[i] for i = 1:n) + sum(tau * d[i] for i = (n+1):2n) |
| 95 | + ) |
| 96 | + |
| 97 | + for i = 1:n |
| 98 | + c = JuMP.@constraint(m, y[i] - sum(X[i, :] .* beta) + d[i] - d[n+i] == 0) |
| 99 | + end |
| 100 | + |
| 101 | + for i = 1:(2n) |
| 102 | + JuMP.@constraint(m, d[i] >= 0) |
| 103 | + end |
| 104 | + |
| 105 | + JuMP.optimize!(m) |
| 106 | + |
| 107 | + betahats = JuMP.value.(beta) |
| 108 | + residuals = y .- X * betahats |
| 109 | + |
| 110 | + result = Dict() |
| 111 | + result["betas"] = betahats |
| 112 | + result["residuals"] = residuals |
| 113 | + result["model"] = m |
| 114 | + return result |
| 115 | +end |
| 116 | + |
| 117 | +end # end of module QuantileRegression |
0 commit comments