Repository navigation
Expand file tree
/
Copy pathSubset Methods.R
More file actions
307 lines (243 loc) · 10.6 KB
/
Copy pathSubset Methods.R
File metadata and controls
307 lines (243 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
rm(list=ls()) #use this to clear the variables
##### Applied #####
library(wooldridge)
### Section 1 ###
help(wage2)
## 1.
#wage: monthly earnings
#hours: average weekly hours
#IQ: IQ score
#KWW: knowledge of world work score
#educ: years of education
#exper: years of work experience
#tenure: years with current employer
#age: age in years
#married: =1 if married
#black: =1 if black
#south: =1 if live in south
#urban: =1 if live in SMSA
#sibs: number of siblings
#brthord: birth order
#meduc: mother's education
#feduc: father's education
#lwage: natural log of wage
## 2.
#I would think the following variables are important in the prediction of wage:
#hours, IQ, KWW, educ, exper, tenure, age, married, black, south, urban, sibs,
#brthord, meduc, feduc
#lwage is excluded as it does not contribute to the prediction of wage. Including it
#could instead make things worse.
### Section 2 ###
df = wage2
## 1.
#Remove rows that contain at least one missing value
df = na.omit(df)
## 2.
#Set the training set size:
trsize=500
#seed of the random number generator for replicability
set.seed(2457829)
#randomly generate trsize numbers from 1 to the nrow(df)
trindices = sample(1:nrow(df),trsize)
#get the training sample (getting only rows whose indices are in trindices)
train = df[trindices,]
#get the testing sample (remove rows whose indices are in trindices)
test = df[-trindices,]
### Section 3 ###
library(leaps)
## 1.
#This is the formula used in `regsubsets()`
fml = formula(wage~poly(hours,degree = 3,raw = TRUE)
+poly(IQ,degree = 3,raw = TRUE)
+poly(KWW,degree = 3,raw = TRUE)
+poly(educ,degree = 3,raw = TRUE)
+poly(exper,degree = 3,raw = TRUE)
+poly(tenure,degree = 3,raw = TRUE)
+married
+black
+south
+urban
+poly(sibs,degree = 3,raw = TRUE)
+poly(brthord,degree = 3,raw = TRUE)
+poly(meduc,degree = 3,raw = TRUE)
+poly(feduc,degree = 3,raw = TRUE))
test_mat = model.matrix(fml, data = test)
#34 regressors
## 2.
maxregno = 20 #Max number of regressors
bss = regsubsets(fml, data = train, nvmax = maxregno, method = "exhaustive")
bss_sum = summary(bss)
#Finding BIC and AIC for "variance estimate from the model"
#Find which position in `bic` is the lowest `bic`.
#This position corresponds to the `k` (number of variables).
kbic=which.min(bss_sum$bic)
#Find which position in `aic` is the lowest `aic`.
#This position corresponds to the `k` (number of variables).
kaic=which.min(bss_sum$cp)
#Finding BIC and AIC for "variance from the largest model" when P << N
#estimate error variance of the model with k=20
errvar= bss_sum$rss[maxregno]/(trsize - maxregno - 1) #trsize-maxregno-1 because there are 20 regressors and 1 constant
#construct the IC using `errvar`, _man is for 'manual'
bic_man = bss_sum$rss/trsize + log(trsize)*errvar*((1:maxregno)/trsize)
aic_man = bss_sum$rss/trsize + 2*errvar*((1:maxregno)/trsize)
#BIC choice
kbic_man=which.min(bic_man)
#AIC choice
kaic_man=which.min(aic_man)
#Finding BIC and AIC for "iterative variance" when when P is relative large w.r.t N
i = 1 #i denotes number of iteration
varYbic = var(train$wage) #sample variance of Y
varYaic = var(train$wage) #sample variance of Y
kbic_temp = 0; kaic_temp = 0
repeat{
if (i > 1){ ## For iteration after the first, we need to update the error variance
varYbic = bss_sum$rss[kbic_iter]/(trsize-kbic_iter-1)
varYaic = bss_sum$rss[kaic_iter]/(trsize-kaic_iter-1)
}
bic_iter = bss_sum$rss/trsize + log(trsize)*varYbic*((1:maxregno)/trsize)
aic_iter = bss_sum$rss/trsize + 2*varYaic*((1:maxregno)/trsize)
#Select best models
kbic_iter = which.min(bic_iter)
kaic_iter = which.min(aic_iter)
if (kbic_temp == kbic_iter & kaic_temp == kaic_iter){
break #when convergence occurs, stop the loop
}
#store this iteration s' choice of k to compare with the new ones later.
kbic_temp = kbic_iter
kaic_temp = kaic_iter
i = i +1
}
#In general, all 3 methods for AIC picked a more complex model (k = 12) as compared to all 3
#methods of BIC which picked a less complex model (k = 6).
#The reasoning for this is because for this training size at trsize = 500, the model complexity penalty
#term for BIC is higher than AIC.
## 3.
#Display a message about best choices:
cat('Best subset selection','\n')
cat('BIC best k: ',kbic ,'\n')
cat('AIC best k: ',kaic ,'\n')
cat('BIC best k - variance from biggest model: ',kbic_man,'\n')
cat('AIC best k - variance from biggest model: ',kaic_man,'\n')
cat('BIC best k - variance from iterative variance: ',kbic_iter,'\n')
cat('AIC best k - variance from iterative variance: ',kaic_iter,'\n')
### Section 4 ###
## 1.
#BIC
#OOS MSE from from all 3 methods
chosen_coefs = coef(bss, id = kbic)
bic_vars = names(chosen_coefs)
predicted = test_mat[,bic_vars]%*%chosen_coefs
truevals = test$wage
bic_mse = mean((truevals-predicted)^2)
#AIC:
#OOS MSE from all 3 methods
chosen_coefs = coef(bss, id = kaic)
aic_vars = names(chosen_coefs)
predicted = test_mat[,aic_vars]%*%chosen_coefs
truevals = test$wage
aic_mse = mean((truevals-predicted)^2)
### Section 5 ###
## 1.1
fml_expand = formula(wage~poly(cbind(hours,IQ, KWW, educ, exper, tenure,sibs, brthord,meduc,feduc), degree = 3,raw=TRUE)
+married
+black
+south
+urban)
test_mat_for = model.matrix(fml_expand, data = test)
#289 regressors
## 1.2.
maxregno_bfs = 20
bfs = regsubsets(fml_expand, data = train, nvmax = maxregno_bfs, method = "forward")
bfs_sum = summary(bfs)
#Finding BIC and AIC for "variance estimate from the model"
#Information criteria
kbic_for=which.min(bfs_sum$bic) #BIC choice
kaic_for=which.min(bfs_sum$cp) #AIC choice (AIC proportional to Cp)
#Finding BIC and AIC for "variance from the largest model" when P << N
#estimate error variance of the model with k=20
errvar_for =bfs_sum$rss[maxregno_bfs]/(trsize - maxregno_bfs - 1)
#construct the IC with this estimate:
## (NOTE: #man: for manual; for: for forward_
bic_man_for = bfs_sum$rss/trsize + log(trsize)*errvar_for*((1:maxregno_bfs)/trsize)
aic_man_for = bfs_sum$rss/trsize + 2*errvar_for*((1:maxregno_bfs)/trsize)
kbic_man_for=which.min(bic_man_for) #BIC choice
kaic_man_for=which.min(aic_man_for) #AIC choice (AIC proportional to Cp and so ranking is the same)
#Finding BIC and AIC for "iterative variance" when when P is relative large w.r.t N
i = 1 #i denotes number of iteration
varYbic_for = var(train$wage) #sample variance of Y
varYaic_for = var(train$wage) #sample variance of Y
kbic_temp_for = 0; kaic_temp_for = 0
repeat{
if (i > 1){ ## For iteration after the first, we need to update the error variance
varYbic_for = bfs_sum$rss[kbic_iter_for]/(trsize-kbic_iter_for-1)
varYaic_for = bfs_sum$rss[kaic_iter_for]/(trsize-kaic_iter_for-1)
### NOTE: (trsize-kaic_iter_for-1) is the degree of freedom
#### (accounted for how many variables are involved)
}
bic_iter_for = bfs_sum$rss/trsize +
log(trsize)*varYbic_for*((1:maxregno_bfs)/trsize)
aic_iter_for = bfs_sum$rss/trsize +
2*varYaic_for*((1:maxregno_bfs)/trsize)
#Select best models
kbic_iter_for = which.min(bic_iter_for)
kaic_iter_for = which.min(aic_iter_for)
if (kbic_temp_for == kbic_iter_for & kaic_temp_for == kaic_iter_for){
break #when convergence occurs, stop the loop
}
#store this iteration s' choice of k to compare with the new ones later.
kbic_temp_for = kbic_iter_for
kaic_temp_for = kaic_iter_for
i = i +1
}
#In general, all 3 methods for AIC picked a more complex model (k = 17 and K = 19) as compared to all 3
#methods of BIC which picked a less complex model (k = 5).
#The reasoning for this is because for this training size at trsize = 500, the model complexity penalty
#term for BIC is higher than AIC.
## 1.3.
#Display a message about best choices:
cat('Forward stepwise selection','\n')
cat('BIC best k: ',kbic_for ,'\n')
cat('AIC best k: ',kaic_for ,'\n')
cat('BIC best k - variance from biggest model: ',kbic_man_for,'\n')
cat('AIC best k - variance from biggest model: ',kaic_man_for,'\n')
cat('BIC best k - variance from iterative variance: ',kbic_iter_for,'\n')
cat('AIC best k - variance from iterative variance: ',kaic_iter_for,'\n')
## 1.4.
#BIC
#OOS MSE from from all 3 methods
chosen_coefs = coef(bfs, id = kbic_for)
bic_vars = names(chosen_coefs)
predicted = test_mat_for[,bic_vars]%*%chosen_coefs
truevals = test$wage
bic_mse_for_5 = mean((truevals-predicted)^2)
#AIC:
#OOS MSE from "variance estimate from the model"
chosen_coefs = coef(bfs, id = kaic_for)
aic_vars = names(chosen_coefs)
predicted = test_mat_for[,aic_vars]%*%chosen_coefs
truevals = test$wage
aic_mse_for_17 = mean((truevals-predicted)^2)
#OOS MSE from other 2 methods
chosen_coefs = coef(bfs, id = kaic_man_for)
aic_vars = names(chosen_coefs)
predicted = test_mat_for[,aic_vars]%*%chosen_coefs
truevals = test$wage
aic_mse_for_19 = mean((truevals-predicted)^2)
## 2.
#Question: Can we perform best subset selection in step 9? Explain why or why not.
#Answer:
#No we cannot. This is due to computational reasons where it is not viable to apply best subset selection on very large p.
#The search space is very large with a number of 2^289 possible models in this case. Forward stepwise selection which explores
#a far more restricted set of models (1+(289(289+1)/2 = 41,906 models in this case) is much more attractive.
#Question: Why is the test MSE of the model chosen by AIC is bigger than the test MSE of the model chosen by BIC,
#even though the number of regressors chosen by AIC is bigger than that chosen by BIC?
#Answer:
#By increasing the number of regressors of the model,it only reduces the in-sample MSE or training error.
#However, the test MSE is using out-of-sample wage values. The test MSE accounts for the bias-variance trade-off
#which means that there is now a penalty term for model complexity. This is why the test MSE for AIC is bigger despite
#having more regressors as the penalty term increased more than the reduction in bias.
## 3.
#Question: Why consistently the number of regressors chosen by BIC is smaller than that chosen by AIC?
#Answer:
#The reasoning for this is because for this training size at trsize = 500, the model complexity penalty term for BIC is higher than AIC.
#For BIC it is log(500)*k = 2.70*k while for AIC it is 2*k.