Функция lm

На прошлой посиделке мы узнали, что можно обучить линейную регрессию с помощью функции lm. Наши данные находятся в датасете data. Мы хотим предсказать заработную плату человека (income). Нашим единственныи признаком является количество лет, которые человек отучился (education).

##                                               
## 1 function (x, df1, df2, ncp, log = FALSE)    
## 2 {                                           
## 3     if (missing(ncp))                       
## 4         .Call(C_df, x, df1, df2, log)       
## 5     else .Call(C_dnf, x, df1, df2, ncp, log)
## 6 }

Нарисуем график рассеяния этих двух переменных. На этом графике мы видим линейную зависимость переменных.

Обучим линейную регрессию.

В переменной model находится наша модель. Она имеет тип list. Из него можно получить значение коэффициентов или ошибки, совершенные моделью.

Также можно получить более подробную информацию с помощью функции summary.

## 
## Call:
## lm(formula = income ~ education, data = data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -15538.4  -2544.3    581.5   2725.4   7689.2 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  13964.3     2232.9   6.254 1.03e-07 ***
## education     4742.3      159.2  29.783  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4550 on 48 degrees of freedom
## Multiple R-squared:  0.9487, Adjusted R-squared:  0.9476 
## F-statistic:   887 on 1 and 48 DF,  p-value: < 2.2e-16

Интерпретация полученных коэффициентов

Из модели мы видим:

  • Cвободный коэффициент равен 8683. Это означает, что в среднем человек, который проучился 0 лет будет зарабатывать 8683 рубля.
  • Коэффициент перед переменной education равен 5091. Это означает, что если человек учится на один год больше, то в среднем он начинает зарабывать на 5091 рубль больше.

Эти оценки могут быть неточными. Чтобы получить доверительный интервалы, можно использовать функцию confint.

##                2.5 %    97.5 %
## (Intercept) 9474.648 18453.873
## education   4422.140  5062.432

Выбросы

Выбросы очень сильно влияют на линейную регрессию.

На графике видно, что видимо кто-то указал зарплату не в рублях, а в долларах. Попробуем оценить линейную регрессию и нарисовать ее.

## 
## Call:
## lm(formula = income ~ education, data = data)
## 
## Coefficients:
## (Intercept)    education  
##       37295         2611

Видно, что линия регрессии проходит не через основное облако точек.

Использование большего количества признаков

Вы можете использовать несколько признаков для построения вашей модели.

Для этого в формуле вам нужно просто перечислить те, которые вы хотите использовать.

## 
## Call:
## lm(formula = y ~ x1 + x2 + x3, data = df)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -4.255e-14 -1.313e-15 -3.270e-16  1.294e-15  3.416e-14 
## 
## Coefficients:
##               Estimate Std. Error    t value Pr(>|t|)    
## (Intercept)  5.000e+00  9.760e-15  5.123e+14   <2e-16 ***
## x1           2.000e+00  6.254e-16  3.198e+15   <2e-16 ***
## x2          -3.000e+00  3.402e-16 -8.819e+15   <2e-16 ***
## x3          -7.312e-17  6.935e-16 -1.050e-01    0.916    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 6.196e-15 on 96 degrees of freedom
## Multiple R-squared:      1,  Adjusted R-squared:      1 
## F-statistic: 1.286e+32 on 3 and 96 DF,  p-value: < 2.2e-16

Категориальные переменные

Давайте рассмотрим следующий набор данных.

Изначально кажется, что тут имеется линейная зависимость и можно провести одну линию регрессии.

Но если попробовать покрасить точки, используя переменную type, то можно понять, что доход зависит от типа образования, которое получил человек.

Бинарная переменная

Чтобы отобразить это в моделе можно закодировать нашу переменную type в 0, если образование college, и в 1, если образование university. Это можно сделать с помощью функции ifelse.

## # A tibble: 6 x 4
##   education type       income type_encode
##       <dbl> <chr>       <dbl>       <dbl>
## 1      9.67 college    51830.           0
## 2      5.53 university 72208.           1
## 3      7.64 college    49063.           0
## 4      7.89 university 80150.           1
## 5      6.90 college    45046.           0
## 6      6.33 university 70655.           1

Попробуем обучить эту модель используя бинарную переменную.

## 
## Call:
## lm(formula = income ~ education + type_encode, data = data)
## 
## Coefficients:
## (Intercept)    education  type_encode  
##       12024         4885        29895

Коэффициент перед type_encode показывает на сколько в среднем человек с высшим образованием зарабатывает больше чем человек со средним образованием.

Label Encoding

Что делать, если переменная принимает больше двух значений?

## # A tibble: 6 x 3
##   education type        income
##       <dbl> <chr>        <dbl>
## 1      3.88 college     20058.
## 2      7.87 university  81797.
## 3      7.13 PhD         97475.
## 4      9.42 college     58450.
## 5      9.38 university  90140.
## 6      8.70 PhD        107226.

Визуализируем данные.

Давайте просто закодируем переменную как в прошлый раз.

## # A tibble: 6 x 4
##   education type        income type_encode
##       <dbl> <chr>        <dbl>       <dbl>
## 1      3.88 college     20058.           1
## 2      7.87 university  81797.           2
## 3      7.13 PhD         97475.           3
## 4      9.42 college     58450.           1
## 5      9.38 university  90140.           2
## 6      8.70 PhD        107226.           3

Обучим модель.

## 
## Call:
## lm(formula = income ~ education + type_encode, data = data)
## 
## Coefficients:
## (Intercept)    education  type_encode  
##      -13907         5015        25022

Смотрим на результат.

Такой подход не очень хорош. Попробуем закодировать наши переменные по-другому.

## # A tibble: 6 x 4
##   education type        income type_encode
##       <dbl> <chr>        <dbl>       <dbl>
## 1      3.88 college     20058.           1
## 2      7.87 university  81797.           3
## 3      7.13 PhD         97475.           2
## 4      9.42 college     58450.           1
## 5      9.38 university  90140.           3
## 6      8.70 PhD        107226.           2

Обучим модель.

## 
## Call:
## lm(formula = income ~ education + type_encode, data = data)
## 
## Coefficients:
## (Intercept)    education  type_encode  
##        7221         4945        14922

Смотрим на результат.

В данном случае кодировка очень важна, потому что 1 и 2 ближе чем 1 и 3.

One Hot Encoding

Чтобы избежать проблем с Label Encoding можно использовать One Hot Encoding (OHE).

Можно использовать готовую функцию. В качестве аргумента вы подаете ваш датасет, в котором все переменные, которые вы хотите закодировать являются факторными.

## # A tibble: 6 x 3
##   education type        income
##       <dbl> <chr>        <dbl>
## 1      7.52 college     42433.
## 2      7.54 university  78656.
## 3      9.30 PhD        109513.
## 4      7.54 college     42139.
## 5      7.98 university  85471.
## 6      5.96 PhD         92444.

Попробуем на нашем датасете.

## # A tibble: 6 x 5
##   education `type=college` `type=PhD` `type=university`  income
##       <dbl>          <dbl>      <dbl>             <dbl>   <dbl>
## 1      7.52              1          0                 0  42433.
## 2      7.54              0          0                 1  78656.
## 3      9.30              0          1                 0 109513.
## 4      7.54              1          0                 0  42139.
## 5      7.98              0          0                 1  85471.
## 6      5.96              0          1                 0  92444.

Переменных уже много и писать их вручную не очень. Вместо этого можно поставить точку. Тогда все переменные, которые есть в вашем наборе данных будут использованы. В данном случае мы хотим оценить нашу модель без свободного коэффициента, поэтому поставим -1.

## 
## Call:
## lm(formula = income ~ . - 1, data = data)
## 
## Coefficients:
##      education     typecollege         typePhD  typeuniversity  
##           5091            9329           59416           38955

Смотрим на результат.