Математическое моделирование
Цель: исследовать набор данных Auto с помощью линейной регрессионной модели. Задействовав все возможные регрессоры, сделать вывод о пригодности модели для прогноза. Сравнить с методом k ближайших соседей по MSE на тестовой выборке.
# загрузка пакетов
library('GGally') # графики совместного разброса переменных
## Warning: package 'GGally' was built under R version 3.4.3
library('lmtest') # тесты остатков регрессионных моделей
## Warning: package 'lmtest' was built under R version 3.4.2
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 3.4.2
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library("ISLR")
## Warning: package 'ISLR' was built under R version 3.4.3
data(Auto)
library('GGally') # графики совместного разброса переменных
library('lmtest') # тесты остатков регрессионных моделей
library('FNN')
## Warning: package 'FNN' was built under R version 3.4.3
# константы
my.seed <- 12345
train.percent <- 0.85
str(Auto)
## 'data.frame': 392 obs. of 9 variables:
## $ mpg : num 18 15 18 16 17 15 14 14 14 15 ...
## $ cylinders : num 8 8 8 8 8 8 8 8 8 8 ...
## $ displacement: num 307 350 318 304 302 429 454 440 455 390 ...
## $ horsepower : num 130 165 150 150 140 198 220 215 225 190 ...
## $ weight : num 3504 3693 3436 3433 3449 ...
## $ acceleration: num 12 11.5 11 12 10.5 10 9 8.5 10 8.5 ...
## $ year : num 70 70 70 70 70 70 70 70 70 70 ...
## $ origin : num 1 1 1 1 1 1 1 1 1 1 ...
## $ name : Factor w/ 304 levels "amc ambassador brougham",..: 49 36 231 14 161 141 54 223 241 2 ...
Auto <- Auto[,-4] #исключаем переменные, которые не участвуют в рассчетах
Auto <- Auto[,-6]
Auto <- Auto[,-6]
Auto <- Auto[,-6]
Auto$cylinders <- as.factor(Auto$cylinders)
# обучающая выборка
set.seed(my.seed)
inTrain <- sample(seq_along(Auto$mpg),
nrow(Auto) * train.percent)
df.train <- Auto[inTrain,]
df.test <- Auto[-inTrain,]
Набор данных Auto содержит переменные:
Размерность обучающей выборки: n=392 строк, p=4 объясняющих переменных. Зависимая переменная – mpg.
summary(Auto)
## mpg cylinders displacement weight acceleration
## Min. : 9.00 3: 4 Min. : 68.0 Min. :1613 Min. : 8.00
## 1st Qu.:17.00 4:199 1st Qu.:105.0 1st Qu.:2225 1st Qu.:13.78
## Median :22.75 5: 3 Median :151.0 Median :2804 Median :15.50
## Mean :23.45 6: 83 Mean :194.4 Mean :2978 Mean :15.54
## 3rd Qu.:29.00 8:103 3rd Qu.:275.8 3rd Qu.:3615 3rd Qu.:17.02
## Max. :46.60 Max. :455.0 Max. :5140 Max. :24.80
# совместный график разброса переменных
ggp <- ggpairs(df.train)
print(ggp, progress = F)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
model.1 <- lm(mpg ~ . + displacement:cylinders + weight:cylinders + acceleration:cylinders,
data = df.train)
summary(model.1)
##
## Call:
## lm(formula = mpg ~ . + displacement:cylinders + weight:cylinders +
## acceleration:cylinders, data = df.train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.4561 -2.2412 -0.0288 1.8979 14.7482
##
## Coefficients: (3 not defined because of singularities)
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -38.29971 43.59766 -0.878 0.38035
## cylinders4 85.49236 43.69160 1.957 0.05126 .
## cylinders5 -15.75152 59.62198 -0.264 0.79181
## cylinders6 76.80410 43.87143 1.751 0.08097 .
## cylinders8 55.25845 43.36275 1.274 0.20348
## displacement 0.01977 0.01407 1.404 0.16120
## weight 0.02155 0.01898 1.135 0.25709
## acceleration 0.67784 0.26250 2.582 0.01027 *
## cylinders4:displacement -0.04929 0.02974 -1.657 0.09843 .
## cylinders5:displacement -0.70720 0.27732 -2.550 0.01124 *
## cylinders6:displacement -0.06504 0.02253 -2.887 0.00416 **
## cylinders8:displacement NA NA NA NA
## cylinders4:weight -0.02877 0.01904 -1.511 0.13188
## cylinders5:weight 0.03274 0.03147 1.040 0.29905
## cylinders6:weight -0.02335 0.01909 -1.223 0.22216
## cylinders8:weight -0.02584 0.01904 -1.358 0.17556
## cylinders4:acceleration -0.54152 0.29379 -1.843 0.06623 .
## cylinders5:acceleration NA NA NA NA
## cylinders6:acceleration -0.86653 0.39141 -2.214 0.02755 *
## cylinders8:acceleration NA NA NA NA
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.968 on 316 degrees of freedom
## Multiple R-squared: 0.7627, Adjusted R-squared: 0.7507
## F-statistic: 63.49 on 16 and 316 DF, p-value: < 2.2e-16
Совместное влияние displacement:cylinders и acceleration:cylinders исключаем, т.к. параметры незначимы и недостаточно наблюдений для оценки одного из них.
model.1 <- lm(mpg ~ . + weight:cylinders,
data = df.train)
summary(model.1)
##
## Call:
## lm(formula = mpg ~ . + weight:cylinders, data = df.train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.6493 -2.3061 -0.2492 2.0121 14.9319
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -25.141458 44.169736 -0.569 0.570
## cylinders4 72.120890 44.157824 1.633 0.103
## cylinders5 53.202929 50.223675 1.059 0.290
## cylinders6 61.333365 44.404557 1.381 0.168
## cylinders8 53.608265 44.284268 1.211 0.227
## displacement -0.014215 0.009132 -1.557 0.121
## weight 0.019785 0.019372 1.021 0.308
## acceleration 0.156472 0.106510 1.469 0.143
## cylinders4:weight -0.027790 0.019401 -1.432 0.153
## cylinders5:weight -0.020285 0.020868 -0.972 0.332
## cylinders6:weight -0.024750 0.019458 -1.272 0.204
## cylinders8:weight -0.022378 0.019404 -1.153 0.250
##
## Residual standard error: 4.054 on 321 degrees of freedom
## Multiple R-squared: 0.7484, Adjusted R-squared: 0.7398
## F-statistic: 86.81 on 11 and 321 DF, p-value: < 2.2e-16
Совместное влияние weight:cylinders тоже исключаем, так как парамеры незначимы
model.1 <- lm(mpg ~ . ,
data = df.train)
summary(model.1)
##
## Call:
## lm(formula = mpg ~ ., data = df.train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.6498 -2.5516 -0.2786 2.4806 15.4552
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 32.0711064 3.4305481 9.349 < 2e-16 ***
## cylinders4 8.8997965 3.0113810 2.955 0.00335 **
## cylinders5 11.1895234 3.8830294 2.882 0.00422 **
## cylinders6 5.4875247 3.2051543 1.712 0.08783 .
## cylinders8 7.9332194 3.5608808 2.228 0.02657 *
## displacement -0.0142011 0.0092457 -1.536 0.12552
## weight -0.0053782 0.0007964 -6.753 6.67e-11 ***
## acceleration 0.1532485 0.1053885 1.454 0.14688
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4.15 on 325 degrees of freedom
## Multiple R-squared: 0.7331, Adjusted R-squared: 0.7274
## F-statistic: 127.5 on 7 and 325 DF, p-value: < 2.2e-16
Параметр acceleration не значим, исключаем его
model.1 <- lm(mpg ~ cylinders + weight + displacement,
data = df.train)
summary(model.1)
##
## Call:
## lm(formula = mpg ~ cylinders + weight + displacement, data = df.train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10.3050 -2.7124 -0.2882 2.4329 15.6107
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 33.5795792 3.2755266 10.252 < 2e-16 ***
## cylinders4 9.6282232 2.9744953 3.237 0.00133 **
## cylinders5 12.1074918 3.8379138 3.155 0.00176 **
## cylinders6 6.3470661 3.1555564 2.011 0.04511 *
## cylinders8 8.5691633 3.5399582 2.421 0.01604 *
## weight -0.0050207 0.0007588 -6.617 1.51e-10 ***
## displacement -0.0188922 0.0086794 -2.177 0.03022 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4.157 on 326 degrees of freedom
## Multiple R-squared: 0.7314, Adjusted R-squared: 0.7264
## F-statistic: 147.9 on 6 and 326 DF, p-value: < 2.2e-16
Все параметры модели значимы, R-квадрат так же достаточно высок, чтобы говорить о прогностической пригодности модели.
bptest(model.1)
##
## studentized Breusch-Pagan test
##
## data: model.1
## BP = 35.525, df = 6, p-value = 3.408e-06
# статистика Дарбина-Уотсона
dwtest(model.1)
##
## Durbin-Watson test
##
## data: model.1
## DW = 2.1989, p-value = 0.9658
## alternative hypothesis: true autocorrelation is greater than 0
# графики остатков
par(mar = c(4.5, 4.5, 2, 1))
par(mfrow = c(1, 3))
plot(model.1, 1)
plot(model.1, 4)
plot(model.1, 5)
par(mfrow = c(1, 1))
# фактические значения y на тестовой выборке
y.fact <- Auto[-inTrain, 1]
y.model.lm <- predict(model.1, df.test)
MSE.lm <- sum((y.model.lm - y.fact)^2) / length(y.model.lm)
# kNN требует на вход только числовые переменные
df.train.num <- as.data.frame(apply(df.train, 2, as.numeric))
df.test.num <- as.data.frame(apply(df.test, 2, as.numeric))
for (i in 2:50){
model.knn <- knn.reg(train = df.train.num[, !(colnames(df.train.num) %in% 'mpg')],
y = df.train.num[, 'mpg'],
test = df.test.num[, !(colnames(df.train.num) %in% 'mpg')], k = i)
y.model.knn <- model.knn$pred
if (i == 2){
MSE.knn <- sum((y.model.knn - y.fact)^2) / length(y.model.knn)
} else {
MSE.knn <- c(MSE.knn,
sum((y.model.knn - y.fact)^2) / length(y.model.knn))
}
}
# график
par(mar = c(4.5, 4.5, 1, 1))
plot(2:50, MSE.knn, type = 'b', col = 'darkgreen',
xlab = 'значение k', ylab = 'MSE на тестовой выборке')
lines(2:50, rep(MSE.lm, 49), lwd = 2, col = grey(0.2), lty = 2)
legend('topright', lty = c(1, 2), pch = c(1, NA),
col = c('darkgreen', grey(0.2)),
legend = c('k ближайших соседа', 'регрессия (все факторы)'),
lwd = rep(2, 2))
Как можно видеть по графику, ошибка регрессии на тестовой выборке меньше, чем ошибка метода k ближайших соседей с k от 2 до 7. Далее с увеличением количества соседей точность kNN скачет, и начиная с 25 MSE на тестовой выборке kNN модели уменьшается. В целом, ошибки на тестовой выборке у моделей двух типов невелики сами по себе. Для малого числа соседей лучше использовать регрессию, а для большего - метод kNN