必要なパッケージを読み込む。
::p_load(tidyverse,
pacman
broom,
rgl,
glmnet,
ISLR, rsample)
次に、ggplot2のテーマとフォントの設定を行う。自分好みの設定がある場合は自由に変えてよい。
if (.Platform$OS.type == "windows") {
if (require(fontregisterer)) {
<- "Yu Gothic"
my_font else {
} <- "Japan1"
my_font
}else if (capabilities("aqua")) {
} <- "HiraginoSans-W3"
my_font else {
} <- "IPAexGothic"
my_font
}
theme_set(theme_gray(base_size = 9,
base_family = my_font))
母数を適当に設定し、その母集団からサイズ\(N\)の標本を抽出する。
set.seed(2021-10-14)
<- 100
N <- 0.8
beta0 <- 2.5
beta1 <- 1.4
beta2 <- runif(N, min = -2, max = 2)
x <- -0.5 * x + rnorm(N, mean = 0, sd = 1) # xとzに相関をもたせる
z <- beta0 + beta1 * x + beta2 * z
mu <- rnorm(N, mean = mu, sd = 2)
y <- tibble(y = y, x = x, z = z) sim_d
抽出した標本の各変数を中心化する。
<- sim_d %>%
sim_d mutate(y_c = y - mean(y),
x_c = x - mean(x),
z_c = z - mean(z))
中心化した変数を用いて最小二乗学習を行う。切片なしを指定するために、formula に-1
を加える
<- lm(y_c ~ -1 + x_c + z_c,
fit1 data = sim_d)
tidy(fit1) %>%
select(term:estimate)
## # A tibble: 2 × 2
## term estimate
## <chr> <dbl>
## 1 x_c 2.46
## 2 z_c 1.70
ここで、さまざまな \(\hat{\boldsymbol{\beta}} = (\hat{\beta}_1, \hat{\beta}_2)\) について、損失(残差平方和) \[ S(\boldsymbol{\beta}) = \sum_{n=1}^N \left( y_n - (\beta_1 x_n + \beta_2 z_n) \right)^2 \] を計算してみよう。
<- function(beta1, beta2) {
LOSS sum((sim_d$y_c - (beta1 * sim_d$x_c + beta2 * sim_d$z_c))^2)
}
<- seq(-1.5, 5, length.out = 500)
b1 <- seq(-1.5, 5, length.out = 500)
b2
<- expand_grid(beta1 = b1, beta2 = b2)
LOSS_D $loss <- LOSS_D %>%
LOSS_Dpmap(.f = LOSS) %>%
unlist()
<- LOSS_D %>%
loss_matrix pull(loss) %>%
matrix(ncol = length(b1),
byrow = TRUE)
計算結果を可視化する。3-D プロットはウェブページに表示できないので、各自で確認されたい。
persp3d(x = b1, y = b2, z = loss_matrix,
xlab = "beta1", ylab = "beta2", zlab = "Loss",
color = "dodgerblue")
最小二乗法で推定された点で、損失(残差平方和)が最小化されていることが確認できる。
同じ結果を等高線図 (contour plot) にする。
<- ggplot(LOSS_D) +
cont1 geom_contour_filled(aes(x = beta1, y = beta2, z = loss)) +
geom_vline(xintercept = coef(fit1)[1],
linetype = "dashed",
color = "gray") +
geom_hline(yintercept = coef(fit1)[2],
linetype = "dashed",
color = "gray") +
scale_fill_brewer(palette = "RdBu",
name = "loss") +
labs(x = expression(beta[1]),
y = expression(beta[2])) +
coord_fixed()
plot(cont1)
この図の中央ほど損失が小さく、図の外側に近づくほど損失が大きくなることがわかる。
パラメタに制約を課さない場合には、パラメタ空間内の任意の点を選べるので、残差平方和\(S(\boldsymbol{\beta})\) を最小化する点(2本の点線が交わる点)をパラメタの推定値と利用する。
パラメタ空間に制約を付けた以下の損失関数を最小化する問題を考える。 \[ L(\boldsymbol{\beta}) = S(\boldsymbol{\beta}) + \lambda |R(\boldsymbol{\beta})| \]
正則化項に\(L_2\)ノルムの二乗を使う。\(\boldsymbol{\beta}\)の\(L_2\)ノルムは、 \[ \|\boldsymbol{\beta}\|_2 = \sqrt{\boldsymbol{\beta}^\top \boldsymbol{\beta}} = \sqrt{\beta_1^2 + \beta_2^2} \] である。
これを使うと、損失関数は、 \[ L(\boldsymbol{\beta}) = S(\boldsymbol{\beta}) + \lambda \| (\boldsymbol{\beta})\|_2^2 \] と、なる。
\(\lambda\)がある程度大きければ、\(L\)を最小化するために\(\|\boldsymbol{\beta}\|_2\) を小さくすることが必要になる。
\(\|\boldsymbol{\beta}\|_2\) を小さくするという制約は、どのようなことを意味するのだろうか。たとえば、 \(\|\boldsymbol{\beta}\|_2^2 \leq 1\) というのはどのような制約だろうか。 \[ \|\boldsymbol{\beta}\|_2^2 = \beta_1^2 + \beta_2^2 \leq 1 \] なので、パラメタ空間が原点を中心とする半径1の円の内側(境界線を含む)に制限されるということである。
この状況を図に表す。
<- tibble(x = seq(-1, 1, length.out = 500),
L2 y_p = sqrt(1 - x^2),
y_n = -1 * y_p) %>%
pivot_longer(cols = y_p:y_n,
names_to = "sign",
values_to = "y")
<- cont1 +
L2_1 geom_path(data = L2, aes(x = x, y = y, group = sign)) +
geom_vline(xintercept = 0,
linetype = "dotted",
color = "black") +
geom_hline(yintercept = 0,
linetype = "dotted",
color = "black") +
coord_fixed()
plot(L2_1)
この例では、\(\|\boldsymbol{\beta}\|_2 \leq 1\) という制約により、\(\hat{\beta}_1\)も\(\hat{\beta}_2\)も0に近づくことがわかる。
実際の分析では、\(\lambda\)の値によって制約の強さを調整する。 また、パラメタの次元は2よりも大きいことがほとんである。
正則化項に\(L_1\)ノルムを使う。\(\boldsymbol{\beta}\)の\(L_1\)ノルムは、 \[ \|\boldsymbol{\beta}\|_1 = |\beta_1| + |\beta_2| \] である。
これを使って損失関数を \[ L(\boldsymbol{\beta}) = S(\boldsymbol{\beta}) + \lambda \|(\boldsymbol{\beta})\|_1 \] と、する。
\(\lambda\)がある程度大きければ、\(L\)を最小化するために\(\|\boldsymbol{\beta}\|_1\) を小さくすることが必要になる。
\(\|\boldsymbol{\beta}\|_1\) を小さくするという制約は、どのようなことを意味するのだろうか。たとえば、 \(\|\boldsymbol{\beta}\|_1 \leq 1\) というのはどのような制約だろうか。 \[ \|\boldsymbol{\beta}\|_1 = |\beta_1| + |\beta_2| \leq 1 \] なので、パラメタ空間が点\((1, 0), (0, 1), (-1, 0), (0, -1)\)を通る正方形の内側(境界線を含む)に制限されるということである。
この状況を図に表す。
<- tibble(x = seq(-1, 1, length.out = 100),
L1 y_p = 1 - abs(x),
y_n = -1 * y_p) %>%
pivot_longer(cols = y_p:y_n,
names_to = "sign",
values_to = "y")
<- cont1 +
L1_1 geom_path(data = L1, aes(x = x, y = y, group = sign)) +
geom_vline(xintercept = 0,
linetype = "dotted",
color = "black") +
geom_hline(yintercept = 0,
linetype = "dotted",
color = "black") +
coord_fixed()
plot(L1_1)
この例では、\(\|\boldsymbol{\beta}\|_1 \leq 1\) という制約により、(おそらく)\(\hat{\boldsymbol{\beta}} = (1, 0)\) になるだろうということがわかる。 このように、\(L_1\)制約を課すと、パラメタの一部がゼロになる。
実際の分析では、\(\lambda\)の値によって制約の強さと調整する。 また、パラメタの次元は2よりも大きいことがほとんである。
ISLR パッケージに含まれるCredit
データを使って実習を行う。
data(Credit)
summary(Credit)
## ID Income Limit Rating
## Min. : 1.0 Min. : 10.35 Min. : 855 Min. : 93.0
## 1st Qu.:100.8 1st Qu.: 21.01 1st Qu.: 3088 1st Qu.:247.2
## Median :200.5 Median : 33.12 Median : 4622 Median :344.0
## Mean :200.5 Mean : 45.22 Mean : 4736 Mean :354.9
## 3rd Qu.:300.2 3rd Qu.: 57.47 3rd Qu.: 5873 3rd Qu.:437.2
## Max. :400.0 Max. :186.63 Max. :13913 Max. :982.0
## Cards Age Education Gender Student
## Min. :1.000 Min. :23.00 Min. : 5.00 Male :193 No :360
## 1st Qu.:2.000 1st Qu.:41.75 1st Qu.:11.00 Female:207 Yes: 40
## Median :3.000 Median :56.00 Median :14.00
## Mean :2.958 Mean :55.67 Mean :13.45
## 3rd Qu.:4.000 3rd Qu.:70.00 3rd Qu.:16.00
## Max. :9.000 Max. :98.00 Max. :20.00
## Married Ethnicity Balance
## No :155 African American: 99 Min. : 0.00
## Yes:245 Asian :102 1st Qu.: 68.75
## Caucasian :199 Median : 459.50
## Mean : 520.01
## 3rd Qu.: 863.00
## Max. :1999.00
これらの変数のうち、応答変数はBalance
(利用残高)であり、個体を識別する変数であるIDを除く変数が特徴量である。
このデータを訓練データ (training data) と検証データ (test data) に分ける。そのために、rsample::initial_split()
を使う。 全体の 3/4 の観測点を訓練用に使うことにする。
set.seed(2021-10-14)
<- initial_split(Credit,
Credit_split prop = 3/4)
<- training(Credit_split) # 訓練(学習)用
Credit_train <- testing(Credit_split) # 検証(テスト)用 Credit_test
nrow(Credit)
## [1] 400
nrow(Credit_train)
## [1] 300
nrow(Credit_test)
## [1] 100
訓練データCredit_train
を使い、応答変数と説明変数をそれぞれ標準化し、別々のオブジェクトとして保存しよう。 変数の標準化には、scale()
関数が使える。
<- Credit_train %>%
y pull(Balance) %>%
scale()
特徴量には、質的変数がいくつか含まれている。 Gender
、Student
、Married
は二値のカテゴリ変数なので、ダミー変数に変換する。 Ethnicity
は3つのカテゴリをもつカテゴリ変数なので、2つのダミー変数を作る。
<- Credit_train %>%
X select(Income:Ethnicity) %>%
mutate(across(where(is.numeric), scale, .names = NULL)) %>%
mutate(Female = ifelse(Gender == "Female", 1, 0),
Student = ifelse(Student == "Yes", 1, 0),
Married = ifelse(Married == "Yes", 1, 0),
African = ifelse(Ethnicity == "African American", 1, 0),
Asian = ifelse(Ethnicity == "Asian", 1, 0)) %>%
select(!c(Gender, Ethnicity)) %>%
as.matrix()
検証用データも同じ形式に揃えておく。
<- Credit_test %>%
y_test pull(Balance) %>%
scale()
<- Credit_test %>%
X_test select(Income:Ethnicity) %>%
mutate(across(where(is.numeric), scale, .names = NULL)) %>%
mutate(Female = ifelse(Gender == "Female", 1, 0),
Student = ifelse(Student == "Yes", 1, 0),
Married = ifelse(Married == "Yes", 1, 0),
African = ifelse(Ethnicity == "African American", 1, 0),
Asian = ifelse(Ethnicity == "Asian", 1, 0)) %>%
select(!c(Gender, Ethnicity)) %>%
as.matrix()
<- lm(y ~ -1 + X)
ols tidy(ols) %>%
select(term, estimate)
## # A tibble: 11 × 2
## term estimate
## <chr> <dbl>
## 1 XIncome -0.593
## 2 XLimit 0.950
## 3 XRating 0.388
## 4 XCards 0.0572
## 5 XAge -0.0402
## 6 XEducation -0.0178
## 7 XStudent 0.929
## 8 XMarried -0.0642
## 9 XFemale -0.0460
## 10 XAfrican -0.0496
## 11 XAsian -0.00583
RSSは、
sum(ols$residuals^2)
## [1] 13.53664
である。
決定係数は、
summary(ols)$r.squared
## [1] 0.9547269
ここで学習した\(\hat{f}_{\mathrm{o}}\) を利用して、検証データの\(y\)を予測してみる。まず、予測値を求める。
<- X_test %*% as.matrix(coef(ols), ncol = 1) pred_ols
予測誤差 \(y - \hat{y}\) の二乗の平均値 (MSE) を計算する。
<- mean((y_test - pred_ols)^2)) (mse_ols
## [1] 0.0490556
制約なしの最小二乗学習の平均二乗誤差は、0.0490556 である。
リッジ回帰を実行するためにglmnet::glmnet()
を使う。glmnet()
は正則化回帰を行うための関数で、リッジ回帰(\(L_2\)制約付き回帰)を実行するには引数 alpha = 0
を指定する。特徴量は既に標準化済みなので standerdize = FALSE
に、切片はないので(応答変数も標準化済みなので) intercetp = FALSE
にする。
<- glmnet(x = X,
ridge y = y,
alpha = 0,
intercept = FALSE,
standardize = FALSE)
glmnet()
は、正則化パラメタ\(\lambda\) (lambda) がさまざまな値をとる場合について、推定対象であるパラメタ\(\boldsymbol{\beta}\)の推定を実行してくれる。推定結果を図示してみよう。
plot(ridge, xvar = "lambda", label = TRUE)
この図の各線が、lambda
の値に応じてそれぞれのパラメタ\(\beta_d\) (\(d = 1, 2, \dots, 11\)) の推定値がどのように変化するかを示している。たとえば、「1」というラベルがついた黒い線は、上で作った特徴量行列X
の第1列であるIncome
(所得)の係数の推定値である。 それぞれの線について、lambda
の値が0のときには、制約なしの最小二乗学習の結果に一致する。lambda
の値が大きくなるにつれて、\(\beta_d\)は0に近づく。
glmnet()
が利用したlambda
の値を確認してみよう。
$lambda ridge
## [1] 856.34662643 780.27115239 710.95401379 647.79481873 590.24651249
## [6] 537.81063915 490.03302428 446.49984103 406.83402579 370.69201225
## [11] 337.76075559 307.75502099 280.41491316 255.50362515 232.80538731
## [16] 212.12359836 193.27912254 176.10873801 160.46372311 146.20856822
## [21] 133.21980200 121.38492197 110.60142006 100.77589474 91.82324201
## [26] 83.66591827 76.23326869 69.46091522 63.29019896 57.66767212
## [31] 52.54463507 47.87671452 43.62347916 39.74808950 36.21697878
## [36] 32.99956221 30.06797206 27.39681629 24.96295864 22.74531820
## [41] 20.72468682 18.88356277 17.20599910 15.67746556 14.28472273
## [46] 13.01570733 11.85942777 10.80586889 9.84590528 8.97122220
## [51] 8.17424354 7.44806628 6.78640060 6.18351547 5.63418900
## [56] 5.13366318 4.67760269 4.26205736 3.88342793 3.53843490
## [61] 3.22409009 2.93767082 2.67669624 2.43890592 2.22224024
## [66] 2.02482254 1.84494289 1.68104325 1.53170400 1.39563164
## [71] 1.27164757 1.15867790 1.05574415 0.96195475 0.87649734
## [76] 0.79863174 0.72768349 0.66303810 0.60413562 0.55046588
## [81] 0.50156401 0.45700644 0.41640725 0.37941478 0.34570861
## [86] 0.31499681 0.28701336 0.26151589 0.23828354 0.21711508
## [91] 0.19782718 0.18025276 0.16423960 0.14964901 0.13635460
## [96] 0.12424123 0.11320399 0.10314726 0.09398394 0.08563466
このように、推定結果として得られたridge
のなかに、全部で100個のlambda
の値が大きい順に保存されていることがわかる。
lambda
の値が最も小さい(\(\lambda\) = 0.0856347)ときのパラメタの推定値を確認しよう。
coef(ridge)[, 100]
## (Intercept) Income Limit Rating Cards Age
## 0.000000000 -0.388885573 0.565717389 0.561347602 0.050374228 -0.053147370
## Education Student Married Female African Asian
## -0.005389409 0.480420539 -0.045802632 -0.012373962 -0.022872021 0.006398403
制約なしの最小二乗学習の結果よりも、それぞれの係数の推定値が0に近づいている(縮小されている)ことがわかる。 このときの、\(L_2\)ノルムを確認する。
coef(ridge)[, 100]^2 %>%
sum() %>%
sqrt()
## [1] 1.012615
lambda
の値が最も大きい(\(\lambda\) = 856.3466264)ときのパラメタの推定値を確認しよう。
coef(ridge)[, 1]
## (Intercept) Income Limit Rating Cards
## 0.000000e+00 4.776402e-37 8.617265e-37 8.649966e-37 1.107144e-37
## Age Education Student Married Female
## -8.467948e-39 -2.817205e-38 9.051341e-38 3.415049e-39 8.674827e-39
## African Asian
## 1.270435e-38 3.062470e-40
すべての係数の推定値がほぼ0になっていることがわかる。このときの\(L_2\)ノルムを確認する。
coef(ridge)[, 1]^2 %>%
sum() %>%
sqrt()
## [1] 1.319279e-36
lambda
の値が大きくなると\(L_2\)ノルムが小さくなることがわかる。
predict()
を使えば、lambda
の値を指定して推定値を得ることができる。 lambda = 50
の場合の推定値を求めてみよう。
predict(ridge, s = 50, type = "coefficients")
## 12 x 1 sparse Matrix of class "dgCMatrix"
## s1
## (Intercept) .
## Income 8.761427e-03
## Limit 1.627683e-02
## Rating 1.633978e-02
## Cards 2.109893e-03
## Age -2.646197e-04
## Education -5.130363e-04
## Student 1.789117e-03
## Married 5.385195e-05
## Female 1.675670e-04
## African 2.304232e-04
## Asian 1.042415e-05
lambda
の値が大きいときにはパラメタの推定値が0に近づき、学習の分散が小さくなることが期待できる。代わりに、バイアスは大きくなる。バイアスと分散のバランスをとり、MSE(あるいは他の指標)が小さくなるようにlambda
の値を選んで推定を行う必要がある。
交差検証 (cross validation) と呼ばれる手法(詳細は今後の授業で説明する)を利用して、MSE(平均二乗誤差)が最小になる lambda
を見つける。
<- cv.glmnet(x = X,
ridge_cv y = y,
alpha = 0,
intercept = FALSE,
standardize = FALSE)
plot(ridge_cv)
MSE の最小値。
min(ridge_cv$cvm)
## [1] 0.08606744
MSEを最小にするlambda
の値。
$lambda.min ridge_cv
## [1] 0.08563466
このlambda
の値で\(L_2\)制約を課した最小二乗推定値は、
predict(ridge, s = ridge_cv$lambda.min, type = "coefficients")
## 12 x 1 sparse Matrix of class "dgCMatrix"
## s1
## (Intercept) .
## Income -0.388885573
## Limit 0.565717389
## Rating 0.561347602
## Cards 0.050374228
## Age -0.053147370
## Education -0.005389409
## Student 0.480420539
## Married -0.045802632
## Female -0.012373962
## African -0.022872021
## Asian 0.006398403
である。
ここで学習した\(\hat{f}_{\mathrm{r}}\) を利用して、検証データの\(y\)を予測してみる。まず、予測値を求める。
<- predict(ridge, s = ridge_cv$lambda.min, newx = X_test) pred_ridge
予測誤差 \(y - \hat{y}\) の二乗の平均値 (MSE) を計算する。
<- mean((y_test - pred_ridge)^2)) (mse_ridge
## [1] 0.07501783
\(L_2\)制約付き最小二乗学習の平均二乗誤差は、0.0750178 である。
ラッソの実行にもglmnet::glmnet()
を使う。ラッソでは alpha = 1
を指定する。
<- glmnet(x = X,
lasso y = y,
alpha = 1,
intercept = FALSE,
standardize = FALSE)
推定結果を図示してみよう。
plot(lasso, xvar = "lambda", label = TRUE)
この図の各線が、lambda
の値に応じてそれぞれのパラメタ\(\beta_d\) (\(d = 1, 2, \dots, 11\)) の推定値がどのように変化するかを示している。たとえば、「1」というラベルがついた黒い線は、上で作った特徴量行列X
の第1列であるIncome
(所得)の係数の推定値である。 それぞれの線について、lambda
の値が0のときには、制約なしの最小二乗学習の結果に一致する。lambda
の値が大きくなると、いくつかの\(\beta_d\)がぴったり0になることがわかる。
glmnet()
が利用したlambda
の値を確認してみよう。
$lambda lasso
## [1] 0.856346626 0.780271152 0.710954014 0.647794819 0.590246512 0.537810639
## [7] 0.490033024 0.446499841 0.406834026 0.370692012 0.337760756 0.307755021
## [13] 0.280414913 0.255503625 0.232805387 0.212123598 0.193279123 0.176108738
## [19] 0.160463723 0.146208568 0.133219802 0.121384922 0.110601420 0.100775895
## [25] 0.091823242 0.083665918 0.076233269 0.069460915 0.063290199 0.057667672
## [31] 0.052544635 0.047876715 0.043623479 0.039748090 0.036216979 0.032999562
## [37] 0.030067972 0.027396816 0.024962959 0.022745318 0.020724687 0.018883563
## [43] 0.017205999 0.015677466 0.014284723 0.013015707 0.011859428 0.010805869
## [49] 0.009845905 0.008971222 0.008174244 0.007448066 0.006786401 0.006183515
## [55] 0.005634189 0.005133663 0.004677603 0.004262057 0.003883428 0.003538435
## [61] 0.003224090 0.002937671 0.002676696 0.002438906 0.002222240 0.002024823
## [67] 0.001844943 0.001681043 0.001531704 0.001395632 0.001271648 0.001158678
## [73] 0.001055744
このように、推定結果として得られたlasso
のなかに、全部で73個のlambda
の値が大きい順に保存されていることがわかる。
lambda
の値が最も小さい(\(\lambda\) = 1.0557442)ときのパラメタの推定値を確認しよう。
coef(lasso)[, 73]
## (Intercept) Income Limit Rating Cards Age
## 0.00000000 -0.58805365 0.86146327 0.47165992 0.05243384 -0.03944465
## Education Student Married Female African Asian
## -0.01586052 0.91327095 -0.06494059 -0.04476163 -0.04427810 0.00000000
制約なしの最小二乗学習の結果よりも、推定値が0になったパラメタがあることがわかる。
lambda
の値がそこそこ大きい(\(\lambda\) = 232.8053873)ときのパラメタの推定値を確認しよう。
coef(lasso)[, 15]
## (Intercept) Income Limit Rating Cards Age
## 0.0000000 0.0000000 0.0000000 0.6256267 0.0000000 0.0000000
## Education Student Married Female African Asian
## 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
Rating
以外の推定値がぴったり0になっていることがわかる。また、Rating
の推定値の絶対値は、制約なしの場合の推定値である0.3879896 よりも大きいことがわかる。この結果から、ラッソは説明変数の選択を行っていると考えることができる。
lambda
の値が最も大きい(\(\lambda\) = 856.3466264)ときのパラメタの推定値を確認しよう。
coef(lasso)[, 1]
## (Intercept) Income Limit Rating Cards Age
## 0 0 0 0 0 0
## Education Student Married Female African Asian
## 0 0 0 0 0 0
すべての係数の推定値がぴったり0になっていることがわかる。
lambda
の値が大きいときにはパラメタの推定値が0に近づき、学習の分散が小さくなることが期待できる。代わりに、バイアスは大きくなる。バイアスと分散のバランスをとり、MSE(あるいは他の指標)が小さくなるようにlambda
の値を選んで推定を行う必要がある。
<- cv.glmnet(x = X,
lasso_cv y = y,
alpha = 1,
intercept = FALSE,
standardize = FALSE)
plot(lasso_cv)
MSEの最小値。
min(lasso_cv$cvm)
## [1] 0.04878917
MSEを最小にするlambda
の値。
$lambda.min lasso_cv
## [1] 0.001531704
このlambda
の値を使って\(L_1\)制約を課した最小二乗学習による推定値は、
predict(lasso, s = lasso_cv$lambda.min, type = "coefficients")
## 12 x 1 sparse Matrix of class "dgCMatrix"
## s1
## (Intercept) .
## Income -0.58581081
## Limit 0.85045185
## Rating 0.48038868
## Cards 0.05160024
## Age -0.03914746
## Education -0.01518219
## Student 0.90704914
## Married -0.06444820
## Female -0.04398252
## African -0.04249131
## Asian .
である。
ここで学習した\(\hat{f}_{\mathrm{l}}\) を利用して、検証データの\(y\)を予測してみよう。まず、予測値を求める。
<- predict(lasso, s = lasso_cv$lambda.min, newx = X_test) pred_lasso
予測誤差 \(y - \hat{y}\) の二乗の平均値 (MSE) を計算する。
<- mean((y_test - pred_lasso)^2)) (mse_lasso
## [1] 0.04848514
\(L_1\)制約付き最小二乗学習の平均二乗誤差は、0.0484851 である。
ここで実行した3つの最小二乗学習について、予測の平均二乗誤差をもう1度確認しよう。
cbind(mse_ols, mse_ridge, mse_lasso)
## mse_ols mse_ridge mse_lasso
## [1,] 0.0490556 0.07501783 0.04848514
この分析例では、ラッソの予測が最も正確であることがわかる。しかし、その結果は、制約なしの最小二乗学習とあまり変わらない。今回の例では、制約を課さなくても、大きな過剰適合は起きていないようである。リッジ回帰の予測力は他の学習法を使った場合に比べて低い。制約を課せば予測性能が必ず良くなるというわけではないことがわかる。