モデル推定
データの読み込み
- 今回の演習では、
lars
パッケージに含まれるdiabetes
データを用います。
data("diabetes")
head(diabetes)
線形回帰モデル
dia.lm <- lm(y~x, data=diabetes)
summary(dia.lm)
Call:
lm(formula = y ~ x, data = diabetes)
Residuals:
Min 1Q Median 3Q Max
-155.829 -38.534 -0.227 37.806 151.355
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 152.133 2.576 59.061 < 2e-16 ***
xage -10.012 59.749 -0.168 0.867000
xsex -239.819 61.222 -3.917 0.000104 ***
xbmi 519.840 66.534 7.813 4.30e-14 ***
xmap 324.390 65.422 4.958 1.02e-06 ***
xtc -792.184 416.684 -1.901 0.057947 .
xldl 476.746 339.035 1.406 0.160389
xhdl 101.045 212.533 0.475 0.634721
xtch 177.064 161.476 1.097 0.273456
xltg 751.279 171.902 4.370 1.56e-05 ***
xglu 67.625 65.984 1.025 0.305998
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 54.15 on 431 degrees of freedom
Multiple R-squared: 0.5177, Adjusted R-squared: 0.5066
F-statistic: 46.27 on 10 and 431 DF, p-value: < 2.2e-16
Ridge回帰モデル
- Ridge回帰モデルとLasso回帰モデルは、
glmnet
パッケージのglmnet()
関数を用いて推定します。
- Ridge回帰モデルは、
glmnet()
関数の引数alpha=0
を指定して推定します。
dia.ridge <- glmnet(diabetes$x, diabetes$y,
# family="gaussian",
alpha=0)
- 回帰係数と\(log(\lambda)\)との関係を可視化します。
plot(dia.ridge, label=TRUE)
- 回帰係数と\(\lambda\)との関係を可視化します。
plot(dia.ridge, xvar="lambda", label=TRUE)
- クロスバリデーションによって、最適な\(\lambda\)を決定します。
dia.ridge.cv <- cv.glmnet(diabetes$x, diabetes$y,
# family="gaussian",
alpha=0)
plot(dia.ridge.cv)
- 左側の縦点線が、MSEが最小となる\(log(\lambda)\)となります。
- Cross-varidated errorの最小値、\(\lambda\)の最小値、及びその対数値は以下の通りになります。
min(dia.ridge.cv$cvm)
[1] 3009.391
dia.ridge.cv$lambda.min
[1] 4.516003
log(dia.ridge.cv$lambda.min)
[1] 1.507627
- 選ばれた\(\lambda\)を、ペナルティと推定値のグラフに描き入れます。
plot(dia.ridge, xvar="lambda", label=TRUE)
abline(v=log(dia.ridge.cv$lambda.min), lty=2)
- MSEが最小となる時の\(\lambda\)に対応するパラメータを出力します。
coef(dia.ridge.cv, s="lambda.min")
11 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) 152.133484
age -1.963374
sex -218.701018
bmi 504.476167
map 309.708936
tc -119.907209
ldl -49.703556
hdl -180.454315
tch 113.546639
ltg 472.886004
glu 80.608255
- MSEが最小となるときのMSEの上側\(1se\)となるときの\(\lambda\)に対応するパラメータを出力します。
coef(dia.ridge.cv, s="lambda.1se")
11 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) 152.1334842
age 26.7106843
sex -99.2102956
bmi 333.5263290
map 217.0738406
tc -0.7188819
ldl -39.5932668
hdl -160.6401985
tch 119.7418295
ltg 285.4877726
glu 112.9543267
pred_dia.ridge.cv <- predict(dia.ridge.cv, s="lambda.min", newx=diabetes$x)
head(pred_dia.ridge.cv)
1
[1,] 201.43621
[2,] 72.08768
[3,] 173.52631
[4,] 162.54031
[5,] 128.40638
[6,] 104.37765
Lasso回帰モデル
- Lasso回帰モデルは、
glmnet()
関数の引数alpha=1
を指定して推定します。
dia.lasso <- glmnet(diabetes$x, diabetes$y,
# family="gaussian",
alpha=1)
- 回帰係数と\(log(\lambda)\)との関係を可視化します。
plot(dia.lasso, label=TRUE)
- 回帰係数と\(\lambda\)との関係を可視化します。
plot(dia.lasso, xvar="lambda", label=TRUE)
- クロスバリデーションによって、最適な\(\lambda\)を決定します。
dia.lasso.cv <- cv.glmnet(diabetes$x, diabetes$y,
# family="gaussian",
alpha=1)
plot(dia.lasso.cv)
- 左側の縦点線が、MSEが最小となる\(log(\lambda)\)となります。
- Cross-varidated errorの最小値、\(\lambda\)の最小値、及びその対数値は以下の通りになります。
min(dia.lasso.cv$cvm)
[1] 2986.619
dia.lasso.cv$lambda.min
[1] 0.0735996
log(dia.lasso.cv$lambda.min)
[1] -2.609116
- 選ばれた\(\lambda\)を、ペナルティと推定値のグラフに描き入れます。
plot(dia.lasso, xvar="lambda", label=TRUE)
abline(v=log(dia.lasso.cv$lambda.min), lty=2)
- MSEが最小となる時の\(\lambda\)に対応するパラメータを出力します。
coef(dia.lasso.cv, s="lambda.min")
11 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) 152.13348
age -6.62609
sex -235.98713
bmi 522.13081
map 321.24746
tc -565.68036
ldl 298.49852
hdl .
tch 145.55907
ltg 667.99392
glu 66.80703
- MSEが最小となるときのMSEの上側\(1se\)となるときの\(\lambda\)に対応するパラメータを出力します。
coef(dia.lasso.cv, s="lambda.1se")
11 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) 152.133484
age .
sex -82.922210
bmi 511.428467
map 238.119244
tc .
ldl .
hdl -175.401082
tch .
ltg 451.053356
glu 2.612794
pred_dia.lasso.cv <- predict(dia.lasso.cv, s="lambda.min", newx=diabetes$x)
EN回帰モデル
- EN回帰モデルは、
glmnet()
関数の引数alpha
の値を0〜1の間で指定して推定します。ここではalpha=0.5
とします。
dia.EN <- glmnet(diabetes$x, diabetes$y,
# family="gaussian",
alpha=0.5)
- 回帰係数と\(log(\lambda)\)との関係を可視化します。
plot(dia.EN, label=TRUE)
- 回帰係数と\(\lambda\)との関係を可視化します。
plot(dia.EN, xvar="lambda", label=TRUE)
- クロスバリデーションによって、最適な\(\lambda\)を決定します。
dia.EN.cv <- cv.glmnet(diabetes$x, diabetes$y,
# family="gaussian",
alpha=0.5)
plot(dia.EN.cv)
- 左側の縦点線が、MSEが最小となる\(log(\lambda)\)となります。
- Cross-varidated errorの最小値、\(\lambda\)の最小値、及びその対数値は以下の通りになります。
min(dia.EN.cv$cvm)
[1] 2996.299
dia.EN.cv$lambda.min
[1] 1.506629
log(dia.EN.cv$lambda.min)
[1] 0.409875
- 選ばれた\(\lambda\)を、ペナルティと推定値のグラフに描き入れます。
plot(dia.EN, xvar="lambda", label=TRUE)
abline(v=log(dia.EN.cv$lambda.min), lty=2)
- MSEが最小となる時の\(\lambda\)に対応するパラメータを出力します。
coef(dia.EN.cv, s="lambda.min")
11 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) 152.13348
age .
sex -203.45857
bmi 519.20505
map 300.63375
tc -123.93250
ldl .
hdl -205.28618
tch 30.94044
ltg 510.96600
glu 59.80693
- MSEが最小となるときのMSEの上側\(1se\)となるときの\(\lambda\)に対応するパラメータを出力します。
coef(dia.EN.cv, s="lambda.1se")
11 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) 152.133484
age .
sex -11.219144
bmi 475.321772
map 201.859709
tc .
ldl .
hdl -132.714852
tch .
ltg 416.987550
glu 4.915767
pred_dia.EN.cv <- predict(dia.EN.cv, s="lambda.min", newx=diabetes$x)
head(pred_dia.EN.cv)
1
[1,] 203.85801
[2,] 70.69643
[3,] 175.32245
[4,] 162.15954
[5,] 127.52535
[6,] 105.15072
LS0tCnRpdGxlOiAi57Wx6KiI6Kej5p6QUua8lOe/kjkiCiNhdXRob3I6ICJUb21veXVraSBGdXJ1dGFuaSIKI2RhdGU6ICIyMDE5LzgvMTQiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChjYWNoZSA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvciA9IFRSVUUpCmBgYAoKIyMg5ryU57+S44Gu5qaC6KaBCi0gTGFzc2/lm57luLDjg6Ljg4fjg6vjgIFSaWRnZeWbnuW4sOODouODh+ODqwoKIyMjIOazqOaEj+S6i+mghQotIOaFtuaHiee+qeWhvuWkp+WtplNGQ+OBp+mWi+ism+OBl+OBpuOBhOOCi+OAjOe1seioiOino+aekOOAjeOBruaOiOalreWxpeS/ruiAheWQkeOBkeOBrua8lOe/kueUqOODmuODvOOCuOOBp+OBmeOAggotIOW/heOBmuOBl+OCguWFqOOBpuOBruODkOODvOOCuOODp+ODs+OBrlLjgoRPU+OBp+WLleS9nOeiuuiqjeOCkuihjOOBo+OBpuOBhOOBvuOBm+OCk+OAguOBk+OBrua8lOe/kueUqOODmuODvOOCuOOCkuS9nOaIkOOBl+OBpuOBhOOCi+autemajuOBp+OBr+OAgVIzLjYuMOOCkuS9v+OBo+OBpuOBhOOBvuOBmeOAggotIFLjga7mm7TmlrDjgarjganjgavjgojjgorjgIFS44Kz44O844OJ44Gq44Gp44KS5LqI5ZGK54Sh44GX44Gr5aSJ5pu044GZ44KL5aC05ZCI44GM44GC44KK44G+44GZ44CCIAoKIyMg44OH44O844K/5YiG5p6Q44Gu5rqW5YKZCiMjIyDjg5Hjg4PjgrHjg7zjgrjjga7jgqTjg7Pjgrnjg4jjg7zjg6sKLSDku4rlm57jga7mvJTnv5Ljgafjga/jgIHku6XkuIvjga7jg5Hjg4PjgrHjg7zjgrjjgpLkvb/jgYTjgb7jgZnjgIIKYGBge3IgaW5zdGFsbC5wYWNrYWdlcywgZXZhbD1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCmluc3RhbGwucGFja2FnZXMoImdsbW5ldCIpCmluc3RhbGwucGFja2FnZXMoImxhcnMiKQpgYGAKCmBgYHtyIGxpYnJhcnksIGV2YWw9RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnbG1uZXQpCmxpYnJhcnkobGFycykKYGBgCgojIyDjg6Ljg4fjg6vmjqjlrpoKIyMjIOODh+ODvOOCv+OBruiqreOBv+i+vOOBvwotIOS7iuWbnuOBrua8lOe/kuOBp+OBr+OAgWBsYXJzYOODkeODg+OCseODvOOCuOOBq+WQq+OBvuOCjOOCi2BkaWFiZXRlc2Djg4fjg7zjgr/jgpLnlKjjgYTjgb7jgZnjgIIKYGBge3IgZGlhYmV0ZXN9CmRhdGEoImRpYWJldGVzIikKaGVhZChkaWFiZXRlcykKYGBgCgojIyMg57ea5b2i5Zue5biw44Oi44OH44OrCi0g44G+44Ga6YeN5Zue5biw44Oi44OH44Or44KS5o6o5a6a44GX44G+44GZ44CCCmBgYHtyIGRpYS5sbX0KZGlhLmxtIDwtIGxtKHl+eCwgZGF0YT1kaWFiZXRlcykKc3VtbWFyeShkaWEubG0pCmBgYAoKIyMjIFJpZGdl5Zue5biw44Oi44OH44OrCi0gUmlkZ2Xlm57luLDjg6Ljg4fjg6vjgahMYXNzb+WbnuW4sOODouODh+ODq+OBr+OAgWBnbG1uZXRg44OR44OD44Kx44O844K444GuYGdsbW5ldCgpYOmWouaVsOOCkueUqOOBhOOBpuaOqOWumuOBl+OBvuOBmeOAggotIFJpZGdl5Zue5biw44Oi44OH44Or44Gv44CBYGdsbW5ldCgpYOmWouaVsOOBruW8leaVsGBhbHBoYT0wYOOCkuaMh+WumuOBl+OBpuaOqOWumuOBl+OBvuOBmeOAggpgYGB7ciBjb2EucmlkZ2V9CmRpYS5yaWRnZSA8LSBnbG1uZXQoZGlhYmV0ZXMkeCwgZGlhYmV0ZXMkeSwgCiAgICAgICAgICAgICAgICAgICAgIyBmYW1pbHk9ImdhdXNzaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgYWxwaGE9MCkKYGBgCi0g5Zue5biw5L+C5pWw44GoJGxvZyhcbGFtYmRhKSTjgajjga7plqLkv4LjgpLlj6/oppbljJbjgZfjgb7jgZnjgIIKYGBge3IgZGlhLnJpZGdlLnBsb3QxfQpwbG90KGRpYS5yaWRnZSwgbGFiZWw9VFJVRSkKYGBgCi0g5Zue5biw5L+C5pWw44GoJFxsYW1iZGEk44Go44Gu6Zai5L+C44KS5Y+v6KaW5YyW44GX44G+44GZ44CCCmBgYHtyIGRpYS5yaWRnZS5wbG90Mn0KcGxvdChkaWEucmlkZ2UsIHh2YXI9ImxhbWJkYSIsIGxhYmVsPVRSVUUpCmBgYAotIOOCr+ODreOCueODkOODquODh+ODvOOCt+ODp+ODs+OBq+OCiOOBo+OBpuOAgeacgOmBqeOBqiRcbGFtYmRhJOOCkuaxuuWumuOBl+OBvuOBmeOAggpgYGB7ciBkaWEucmlkZ2UuY3Z9CmRpYS5yaWRnZS5jdiA8LSBjdi5nbG1uZXQoZGlhYmV0ZXMkeCwgZGlhYmV0ZXMkeSwgCiAgICAgICAgICAgICAgICAgICAgIyBmYW1pbHk9ImdhdXNzaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgYWxwaGE9MCkKYGBgCi0g44Kv44Ot44K544OQ44Oq44OH44O844K344On44Oz44Gu57WQ5p6c44KS5Y+v6KaW5YyW44GX44G+44GZ44CCCmBgYHtyIGRpYS5yaWRnZS5jdi5wbG90fQpwbG90KGRpYS5yaWRnZS5jdikKYGBgCi0g5bem5YG044Gu57im54K557ea44GM44CBTVNF44GM5pyA5bCP44Go44Gq44KLJGxvZyhcbGFtYmRhKSTjgajjgarjgorjgb7jgZnjgIIKLSBDcm9zcy12YXJpZGF0ZWQgZXJyb3Ljga7mnIDlsI/lgKTjgIEkXGxhbWJkYSTjga7mnIDlsI/lgKTjgIHlj4rjgbPjgZ3jga7lr77mlbDlgKTjga/ku6XkuIvjga7pgJrjgorjgavjgarjgorjgb7jgZnjgIIKYGBge3IgZGlhLnJpZGdlLmN2Lm1zZX0KbWluKGRpYS5yaWRnZS5jdiRjdm0pCmRpYS5yaWRnZS5jdiRsYW1iZGEubWluCmxvZyhkaWEucmlkZ2UuY3YkbGFtYmRhLm1pbikKYGBgCi0g6YG444Gw44KM44GfJFxsYW1iZGEk44KS44CB44Oa44OK44Or44OG44Kj44Go5o6o5a6a5YCk44Gu44Kw44Op44OV44Gr5o+P44GN5YWl44KM44G+44GZ44CCCmBgYHtyIGRpYS5yaWRnZS5jdi5wbG90M30KcGxvdChkaWEucmlkZ2UsIHh2YXI9ImxhbWJkYSIsIGxhYmVsPVRSVUUpCmFibGluZSh2PWxvZyhkaWEucmlkZ2UuY3YkbGFtYmRhLm1pbiksIGx0eT0yKQpgYGAKLSBNU0XjgYzmnIDlsI/jgajjgarjgovmmYLjga4kXGxhbWJkYSTjgavlr77lv5zjgZnjgovjg5Hjg6njg6Hjg7zjgr/jgpLlh7rlipvjgZfjgb7jgZnjgIIKYGBge3IgZGlhLnJpZGdlLmN2LmxhbWJkYS5taW59CmNvZWYoZGlhLnJpZGdlLmN2LCBzPSJsYW1iZGEubWluIikKYGBgCi0gTVNF44GM5pyA5bCP44Go44Gq44KL44Go44GN44GuTVNF44Gu5LiK5YG0JDFzZSTjgajjgarjgovjgajjgY3jga4kXGxhbWJkYSTjgavlr77lv5zjgZnjgovjg5Hjg6njg6Hjg7zjgr/jgpLlh7rlipvjgZfjgb7jgZnjgIIKYGBge3IgZGlhLnJpZGdlLmN2LmxhbWJkYS4xc2V9CmNvZWYoZGlhLnJpZGdlLmN2LCBzPSJsYW1iZGEuMXNlIikKYGBgCi0g5o6o5a6a44GX44Gf44OR44Op44Oh44O844K/44Gr44KI44KL5LqI5ris5YCk44KS5Ye65Yqb44GX44G+44GZ44CCCmBgYHtyIGRpYS5yaWRnZS5jdi5sYW1iZGEubWluLnByZWRpY3R9CnByZWRfZGlhLnJpZGdlLmN2IDwtIHByZWRpY3QoZGlhLnJpZGdlLmN2LCBzPSJsYW1iZGEubWluIiwgbmV3eD1kaWFiZXRlcyR4KQpoZWFkKHByZWRfZGlhLnJpZGdlLmN2KQpgYGAKCiMjIyBMYXNzb+WbnuW4sOODouODh+ODqwotIExhc3Nv5Zue5biw44Oi44OH44Or44Gv44CBYGdsbW5ldCgpYOmWouaVsOOBruW8leaVsGBhbHBoYT0xYOOCkuaMh+WumuOBl+OBpuaOqOWumuOBl+OBvuOBmeOAggpgYGB7ciBjb2EubGFzc299CmRpYS5sYXNzbyA8LSBnbG1uZXQoZGlhYmV0ZXMkeCwgZGlhYmV0ZXMkeSwgCiAgICAgICAgICAgICAgICAgICAgIyBmYW1pbHk9ImdhdXNzaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgYWxwaGE9MSkKYGBgCi0g5Zue5biw5L+C5pWw44GoJGxvZyhcbGFtYmRhKSTjgajjga7plqLkv4LjgpLlj6/oppbljJbjgZfjgb7jgZnjgIIKYGBge3IgZGlhLmxhc3NvLnBsb3QxfQpwbG90KGRpYS5sYXNzbywgbGFiZWw9VFJVRSkKYGBgCi0g5Zue5biw5L+C5pWw44GoJFxsYW1iZGEk44Go44Gu6Zai5L+C44KS5Y+v6KaW5YyW44GX44G+44GZ44CCCmBgYHtyIGRpYS5sYXNzby5wbG90Mn0KcGxvdChkaWEubGFzc28sIHh2YXI9ImxhbWJkYSIsIGxhYmVsPVRSVUUpCmBgYAotIOOCr+ODreOCueODkOODquODh+ODvOOCt+ODp+ODs+OBq+OCiOOBo+OBpuOAgeacgOmBqeOBqiRcbGFtYmRhJOOCkuaxuuWumuOBl+OBvuOBmeOAggpgYGB7ciBkaWEubGFzc28uY3Z9CmRpYS5sYXNzby5jdiA8LSBjdi5nbG1uZXQoZGlhYmV0ZXMkeCwgZGlhYmV0ZXMkeSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmYW1pbHk9ImdhdXNzaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGE9MSkKYGBgCi0g44Kv44Ot44K544OQ44Oq44OH44O844K344On44Oz44Gu57WQ5p6c44KS5Y+v6KaW5YyW44GX44G+44GZ44CCCmBgYHtyIGRpYS5sYXNzby5jdi5wbG90fQpwbG90KGRpYS5sYXNzby5jdikKYGBgCi0g5bem5YG044Gu57im54K557ea44GM44CBTVNF44GM5pyA5bCP44Go44Gq44KLJGxvZyhcbGFtYmRhKSTjgajjgarjgorjgb7jgZnjgIIKLSBDcm9zcy12YXJpZGF0ZWQgZXJyb3Ljga7mnIDlsI/lgKTjgIEkXGxhbWJkYSTjga7mnIDlsI/lgKTjgIHlj4rjgbPjgZ3jga7lr77mlbDlgKTjga/ku6XkuIvjga7pgJrjgorjgavjgarjgorjgb7jgZnjgIIKYGBge3IgZGlhLmxhc3NvLmN2Lm1zZX0KbWluKGRpYS5sYXNzby5jdiRjdm0pCmRpYS5sYXNzby5jdiRsYW1iZGEubWluCmxvZyhkaWEubGFzc28uY3YkbGFtYmRhLm1pbikKYGBgCi0g6YG444Gw44KM44GfJFxsYW1iZGEk44KS44CB44Oa44OK44Or44OG44Kj44Go5o6o5a6a5YCk44Gu44Kw44Op44OV44Gr5o+P44GN5YWl44KM44G+44GZ44CCCmBgYHtyIGRpYS5sYXNzby5jdi5wbG90M30KcGxvdChkaWEubGFzc28sIHh2YXI9ImxhbWJkYSIsIGxhYmVsPVRSVUUpCmFibGluZSh2PWxvZyhkaWEubGFzc28uY3YkbGFtYmRhLm1pbiksIGx0eT0yKQpgYGAKLSBNU0XjgYzmnIDlsI/jgajjgarjgovmmYLjga4kXGxhbWJkYSTjgavlr77lv5zjgZnjgovjg5Hjg6njg6Hjg7zjgr/jgpLlh7rlipvjgZfjgb7jgZnjgIIKYGBge3IgZGlhLmxhc3NvLmN2LmxhbWJkYS5taW59CmNvZWYoZGlhLmxhc3NvLmN2LCBzPSJsYW1iZGEubWluIikKYGBgCi0gTVNF44GM5pyA5bCP44Go44Gq44KL44Go44GN44GuTVNF44Gu5LiK5YG0JDFzZSTjgajjgarjgovjgajjgY3jga4kXGxhbWJkYSTjgavlr77lv5zjgZnjgovjg5Hjg6njg6Hjg7zjgr/jgpLlh7rlipvjgZfjgb7jgZnjgIIKYGBge3IgZGlhLmxhc3NvLmN2LmxhbWJkYS4xc2V9CmNvZWYoZGlhLmxhc3NvLmN2LCBzPSJsYW1iZGEuMXNlIikKYGBgCi0g5o6o5a6a44GX44Gf44OR44Op44Oh44O844K/44Gr44KI44KL5LqI5ris5YCk44KS5Ye65Yqb44GX44G+44GZ44CCCmBgYHtyIGRpYS5sYXNzby5jdi5sYW1iZGEubWluLnByZWRpY3R9CnByZWRfZGlhLmxhc3NvLmN2IDwtIHByZWRpY3QoZGlhLmxhc3NvLmN2LCBzPSJsYW1iZGEubWluIiwgbmV3eD1kaWFiZXRlcyR4KQpoZWFkKHByZWRfZGlhLmxhc3NvLmN2KQpgYGAKCiMjIyBFTuWbnuW4sOODouODh+ODqwotIEVO5Zue5biw44Oi44OH44Or44Gv44CBYGdsbW5ldCgpYOmWouaVsOOBruW8leaVsGBhbHBoYWDjga7lgKTjgpIw44CcMeOBrumWk+OBp+aMh+WumuOBl+OBpuaOqOWumuOBl+OBvuOBmeOAguOBk+OBk+OBp+OBr2BhbHBoYT0wLjVg44Go44GX44G+44GZ44CCCmBgYHtyIGNvYS5lbn0KZGlhLkVOIDwtIGdsbW5ldChkaWFiZXRlcyR4LCBkaWFiZXRlcyR5LCAKICAgICAgICAgICAgICAgICAgICAjIGZhbWlseT0iZ2F1c3NpYW4iLCAKICAgICAgICAgICAgICAgICAgICBhbHBoYT0wLjUpCmBgYAotIOWbnuW4sOS/guaVsOOBqCRsb2coXGxhbWJkYSkk44Go44Gu6Zai5L+C44KS5Y+v6KaW5YyW44GX44G+44GZ44CCCmBgYHtyIGRpYS5lbi5wbG90MX0KcGxvdChkaWEuRU4sIGxhYmVsPVRSVUUpCmBgYAotIOWbnuW4sOS/guaVsOOBqCRcbGFtYmRhJOOBqOOBrumWouS/guOCkuWPr+imluWMluOBl+OBvuOBmeOAggpgYGB7ciBkaWEuZW4ucGxvdDJ9CnBsb3QoZGlhLkVOLCB4dmFyPSJsYW1iZGEiLCBsYWJlbD1UUlVFKQpgYGAKLSDjgq/jg63jgrnjg5Djg6rjg4fjg7zjgrfjg6fjg7PjgavjgojjgaPjgabjgIHmnIDpganjgaokXGxhbWJkYSTjgpLmsbrlrprjgZfjgb7jgZnjgIIKYGBge3IgZGlhLmVuLmN2fQpkaWEuRU4uY3YgPC0gY3YuZ2xtbmV0KGRpYWJldGVzJHgsIGRpYWJldGVzJHksIAogICAgICAgICAgICAgICAgICAgICAgICAgICMgZmFtaWx5PSJnYXVzc2lhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhPTAuNSkKYGBgCi0g44Kv44Ot44K544OQ44Oq44OH44O844K344On44Oz44Gu57WQ5p6c44KS5Y+v6KaW5YyW44GX44G+44GZ44CCCmBgYHtyIGRpYS5lbi5jdi5wbG90fQpwbG90KGRpYS5FTi5jdikKYGBgCi0g5bem5YG044Gu57im54K557ea44GM44CBTVNF44GM5pyA5bCP44Go44Gq44KLJGxvZyhcbGFtYmRhKSTjgajjgarjgorjgb7jgZnjgIIKLSBDcm9zcy12YXJpZGF0ZWQgZXJyb3Ljga7mnIDlsI/lgKTjgIEkXGxhbWJkYSTjga7mnIDlsI/lgKTjgIHlj4rjgbPjgZ3jga7lr77mlbDlgKTjga/ku6XkuIvjga7pgJrjgorjgavjgarjgorjgb7jgZnjgIIKYGBge3IgZGlhLmVuLmN2Lm1zZX0KbWluKGRpYS5FTi5jdiRjdm0pCmRpYS5FTi5jdiRsYW1iZGEubWluCmxvZyhkaWEuRU4uY3YkbGFtYmRhLm1pbikKYGBgCi0g6YG444Gw44KM44GfJFxsYW1iZGEk44KS44CB44Oa44OK44Or44OG44Kj44Go5o6o5a6a5YCk44Gu44Kw44Op44OV44Gr5o+P44GN5YWl44KM44G+44GZ44CCCmBgYHtyIGRpYS5lbi5jdi5wbG90M30KcGxvdChkaWEuRU4sIHh2YXI9ImxhbWJkYSIsIGxhYmVsPVRSVUUpCmFibGluZSh2PWxvZyhkaWEuRU4uY3YkbGFtYmRhLm1pbiksIGx0eT0yKQpgYGAKLSBNU0XjgYzmnIDlsI/jgajjgarjgovmmYLjga4kXGxhbWJkYSTjgavlr77lv5zjgZnjgovjg5Hjg6njg6Hjg7zjgr/jgpLlh7rlipvjgZfjgb7jgZnjgIIKYGBge3IgZGlhLmVuLmN2LmxhbWJkYS5taW59CmNvZWYoZGlhLkVOLmN2LCBzPSJsYW1iZGEubWluIikKYGBgCi0gTVNF44GM5pyA5bCP44Go44Gq44KL44Go44GN44GuTVNF44Gu5LiK5YG0JDFzZSTjgajjgarjgovjgajjgY3jga4kXGxhbWJkYSTjgavlr77lv5zjgZnjgovjg5Hjg6njg6Hjg7zjgr/jgpLlh7rlipvjgZfjgb7jgZnjgIIKYGBge3IgZGlhLmVuLmN2LmxhbWJkYS4xc2V9CmNvZWYoZGlhLkVOLmN2LCBzPSJsYW1iZGEuMXNlIikKYGBgCi0g5o6o5a6a44GX44Gf44OR44Op44Oh44O844K/44Gr44KI44KL5LqI5ris5YCk44KS5Ye65Yqb44GX44G+44GZ44CCCmBgYHtyIGRpYS5lbi5jdi5sYW1iZGEubWluLnByZWRpY3R9CnByZWRfZGlhLkVOLmN2IDwtIHByZWRpY3QoZGlhLkVOLmN2LCBzPSJsYW1iZGEubWluIiwgbmV3eD1kaWFiZXRlcyR4KQpoZWFkKHByZWRfZGlhLkVOLmN2KQpgYGAKCi0g5LuK5Zue44Gu5ryU57+S44Gv5Lul5LiK44Gn44GZ44CC