Подключим пакеты:

library("quantreg") # квантильная регрессия
library("ggplot2") # графики
library("dplyr") # манипуляции с данными

Обычная регрессия предполагает, что условное среднее переменной \(y\) линейно зависит от регрессора \(x\):

\[ E(y_i|x_i) = \beta_1 + \beta_2 x_i \]

Медианная регрессия предполагает, что от регрессоров линейно зависит условная медиана зависимой переменной:

\[ Med(y_i|x_i)=\beta_1+\beta_2 x_i \]

Оценки медианной регрессии находятся путём минимизации суммы модулей. Если, как и в обычной регрессии, обозначить \(\hat y_i = \hat\beta_1 + \hat\beta_2 x_i\), то целевая функция имеет вид:

\[ \sum |y_i - \hat y_i| \to \min_{\hat\beta} \]

Обобщением медианной регрессии является квантильная регрессия. Квантильная регрессия предполагает, что условная квантиль порядка \(\tau\) переменной \(y\) линейно зависит от регрессора \(x\):

\[ q_{\tau}(y_i|x_i)=\beta_1+\beta_2 x_i \]

Здесь \(q_{\tau}\) - это квантиль порядка \(\tau\).

Задача оптимизации для квантильной регрессии имеет вид:

\[ \sum w_i|y_i - \hat y_i| \to \min_{\hat\beta}, \] где веса \(w_i\) показывают, насколько большой штраф получается в зависимости от того, перескочил ли прогноз \(\hat y_i\) фактическое значение \(y_i\)

\[ w_i =\begin{cases} \tau, \text{ если } \hat y_i < y_i \\ 1-\tau, \text{ если } \hat y_i \geq y_i \end{cases} \]

Возьмём встроенный в R набор данных по стоимости бриллиантов и перейдем к логарифму цены бриллианта и логарифму массы:

diams <- mutate(diamonds, 
                log_price = log(price),
                log_carat = log(carat))

Оценим обычную и несколько квантильных регрессий:

model_ols <- lm(data = diams, log_price ~ log_carat)
model_q <- rq(data = diams, log_price ~ log_carat,
              tau = c(0.01, 0.1, 0.5, 0.9, 0.99))

Посмотрим на описания всех пяти моделей

summary(model_q)
## 
## Call: rq(formula = log_price ~ log_carat, tau = c(0.01, 0.1, 0.5, 0.9, 
##     0.99), data = diams)
## 
## tau: [1] 0.01
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   7.73780   0.02101  368.23594   0.00000
## log_carat     1.49805   0.02482   60.35184   0.00000
## 
## Call: rq(formula = log_price ~ log_carat, tau = c(0.01, 0.1, 0.5, 0.9, 
##     0.99), data = diams)
## 
## tau: [1] 0.1
## 
## Coefficients:
##             Value      Std. Error t value    Pr(>|t|)  
## (Intercept)    8.13418    0.00219 3706.09415    0.00000
## log_carat      1.69432    0.00326  519.66516    0.00000
## 
## Call: rq(formula = log_price ~ log_carat, tau = c(0.01, 0.1, 0.5, 0.9, 
##     0.99), data = diams)
## 
## tau: [1] 0.5
## 
## Coefficients:
##             Value      Std. Error t value    Pr(>|t|)  
## (Intercept)    8.43377    0.00156 5420.28232    0.00000
## log_carat      1.65124    0.00236  699.07418    0.00000
## 
## Call: rq(formula = log_price ~ log_carat, tau = c(0.01, 0.1, 0.5, 0.9, 
##     0.99), data = diams)
## 
## tau: [1] 0.9
## 
## Coefficients:
##             Value      Std. Error t value    Pr(>|t|)  
## (Intercept)    8.80055    0.00306 2875.63314    0.00000
## log_carat      1.71922    0.00313  548.93883    0.00000
## 
## Call: rq(formula = log_price ~ log_carat, tau = c(0.01, 0.1, 0.5, 0.9, 
##     0.99), data = diams)
## 
## tau: [1] 0.99
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   9.15211   0.01928  474.77492   0.00000
## log_carat     1.83616   0.02236   82.11804   0.00000

В квантильной регрессии нет явных формул для оценок дисперсий коэффициентов. Существует несколько алгоритмов подсчёта оценок. По умолчанию используется алгоритм Губера, можно использовать бутстрэп, но он здесь очень долго думает:

summary(model_q, se = "boot")

Можно на графике посмотреть, как меняются коэффициенты при изменении квантиля:

plot(model_q)

На графике видно, что у самых дорогих бриллиантов цена более чувствительна к массе, чем у самых дешёвых. Для бриллиантов в среднем ценовом диапазоне эластичность цены по массе стабильна.

Изобразим на одном графике линию обычной регрессии и линии квантильных регрессий.

base <- ggplot(data = diams, aes(x = log_carat, y = log_price)) + 
  geom_point() + ggtitle("Зависимость цены от массы бриллианта") +
  xlab("Логарифм массы в каратах") + ylab("Логарифм цены в долларах")
base + stat_smooth(method = "lm", se = FALSE) +
  stat_smooth(method = "rq", se = FALSE, method.args = list(tau = 0.01), col = "red") +
  stat_smooth(method = "rq", se = FALSE, method.args = list(tau = 0.99), col = "red") 

Без опции se = FALSE при методе rq вылезает ошибка.

Todo:

Почиташки: