###Goal: To Search for the best prediction model using evaluation criteria RMS(P)E for testing Data
##Exploring Boston Housing Data:
###Packages
library(MASS)
library(glmnet)
## Warning: package 'glmnet' was built under R version 4.3.2
## Loading required package: Matrix
## Warning: package 'Matrix' was built under R version 4.3.2
## Loaded glmnet 4.1-8
library(plotmo)
## Warning: package 'plotmo' was built under R version 4.3.2
## Loading required package: Formula
## Loading required package: plotrix
## Warning: package 'plotrix' was built under R version 4.3.2
## Loading required package: TeachingDemos
## Warning: package 'TeachingDemos' was built under R version 4.3.2
library(rpart)
library(rpart.plot)
## Warning: package 'rpart.plot' was built under R version 4.3.2
library(boot)
data(Boston)
attach(Boston)
dim(Boston)
## [1] 506 14
str(Boston)
## 'data.frame': 506 obs. of 14 variables:
## $ crim : num 0.00632 0.02731 0.02729 0.03237 0.06905 ...
## $ zn : num 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
## $ indus : num 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
## $ chas : int 0 0 0 0 0 0 0 0 0 0 ...
## $ nox : num 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
## $ rm : num 6.58 6.42 7.18 7 7.15 ...
## $ age : num 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
## $ dis : num 4.09 4.97 4.97 6.06 6.06 ...
## $ rad : int 1 2 2 3 3 3 5 5 5 5 ...
## $ tax : num 296 242 242 222 222 222 311 311 311 311 ...
## $ ptratio: num 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
## $ black : num 397 397 393 395 397 ...
## $ lstat : num 4.98 9.14 4.03 2.94 5.33 ...
## $ medv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
summary(Boston)
## crim zn indus chas
## Min. : 0.00632 Min. : 0.00 Min. : 0.46 Min. :0.00000
## 1st Qu.: 0.08205 1st Qu.: 0.00 1st Qu.: 5.19 1st Qu.:0.00000
## Median : 0.25651 Median : 0.00 Median : 9.69 Median :0.00000
## Mean : 3.61352 Mean : 11.36 Mean :11.14 Mean :0.06917
## 3rd Qu.: 3.67708 3rd Qu.: 12.50 3rd Qu.:18.10 3rd Qu.:0.00000
## Max. :88.97620 Max. :100.00 Max. :27.74 Max. :1.00000
## nox rm age dis
## Min. :0.3850 Min. :3.561 Min. : 2.90 Min. : 1.130
## 1st Qu.:0.4490 1st Qu.:5.886 1st Qu.: 45.02 1st Qu.: 2.100
## Median :0.5380 Median :6.208 Median : 77.50 Median : 3.207
## Mean :0.5547 Mean :6.285 Mean : 68.57 Mean : 3.795
## 3rd Qu.:0.6240 3rd Qu.:6.623 3rd Qu.: 94.08 3rd Qu.: 5.188
## Max. :0.8710 Max. :8.780 Max. :100.00 Max. :12.127
## rad tax ptratio black
## Min. : 1.000 Min. :187.0 Min. :12.60 Min. : 0.32
## 1st Qu.: 4.000 1st Qu.:279.0 1st Qu.:17.40 1st Qu.:375.38
## Median : 5.000 Median :330.0 Median :19.05 Median :391.44
## Mean : 9.549 Mean :408.2 Mean :18.46 Mean :356.67
## 3rd Qu.:24.000 3rd Qu.:666.0 3rd Qu.:20.20 3rd Qu.:396.23
## Max. :24.000 Max. :711.0 Max. :22.00 Max. :396.90
## lstat medv
## Min. : 1.73 Min. : 5.00
## 1st Qu.: 6.95 1st Qu.:17.02
## Median :11.36 Median :21.20
## Mean :12.65 Mean :22.53
## 3rd Qu.:16.95 3rd Qu.:25.00
## Max. :37.97 Max. :50.00
##Linear Model
###Random Split Data 80%/20% using #M Number
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
## Building Linear Model Using all the parameter
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
##linear model
#Training data
Boston_lm <- lm(medv ~ ., data = Boston_train)
summary(Boston_lm)
##
## Call:
## lm(formula = medv ~ ., data = Boston_train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -14.758 -2.752 -0.555 1.866 25.618
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 39.004841 5.716033 6.824 3.40e-11 ***
## crim -0.139143 0.039070 -3.561 0.000415 ***
## zn 0.049269 0.015171 3.248 0.001264 **
## indus 0.009785 0.070082 0.140 0.889034
## chas 2.153769 0.975097 2.209 0.027771 *
## nox -17.574187 4.269927 -4.116 4.71e-05 ***
## rm 3.544327 0.470513 7.533 3.49e-13 ***
## age -0.001806 0.015088 -0.120 0.904778
## dis -1.515124 0.229429 -6.604 1.31e-10 ***
## rad 0.321394 0.077346 4.155 4.00e-05 ***
## tax -0.012623 0.004348 -2.903 0.003908 **
## ptratio -0.907784 0.148569 -6.110 2.41e-09 ***
## black 0.006198 0.003440 1.802 0.072361 .
## lstat -0.534372 0.058395 -9.151 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4.893 on 390 degrees of freedom
## Multiple R-squared: 0.7173, Adjusted R-squared: 0.7079
## F-statistic: 76.11 on 13 and 390 DF, p-value: < 2.2e-16
p_lm <- predict(Boston_lm)
In_sample_ASE<-mean((Boston_train$medv - p_lm)^2)
MSE<- (sum((Boston_train$medv - p_lm)^2))/(dim(Boston_train)[1]-13-1)
#Out of sample performance
p_lm_test <- predict(Boston_lm, newdata = Boston_test)
MSPE_out_of_sample <- mean((Boston_test$medv - p_lm_test)^2)
## **For linear Model**:
##MSE
MSE
## [1] 23.94085
##In sample ASE
In_sample_ASE
## [1] 23.11121
## Out of Sample MSPE
MSPE_out_of_sample
## [1] 17.81081
##RMSPE
sqrt(MSPE_out_of_sample)
## [1] 4.220285
##linear model,with only 11 significant predictors, derived from above model summary
#Training data
Boston_lm <- lm(medv ~ crim+zn+chas+nox+rm+dis+rad+tax+ptratio+black+lstat, data = Boston_train)
summary(Boston_lm)
##
## Call:
## lm(formula = medv ~ crim + zn + chas + nox + rm + dis + rad +
## tax + ptratio + black + lstat, data = Boston_train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -14.7245 -2.7669 -0.5492 1.8744 25.5603
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 39.020730 5.678406 6.872 2.50e-11 ***
## crim -0.139294 0.038937 -3.577 0.00039 ***
## zn 0.049297 0.014982 3.290 0.00109 **
## chas 2.163859 0.968105 2.235 0.02597 *
## nox -17.546979 3.942928 -4.450 1.12e-05 ***
## rm 3.525591 0.456572 7.722 9.66e-14 ***
## dis -1.514299 0.211342 -7.165 3.88e-12 ***
## rad 0.319545 0.075056 4.257 2.59e-05 ***
## tax -0.012425 0.004033 -3.081 0.00221 **
## ptratio -0.905022 0.146015 -6.198 1.45e-09 ***
## black 0.006136 0.003411 1.799 0.07281 .
## lstat -0.536057 0.054301 -9.872 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4.881 on 392 degrees of freedom
## Multiple R-squared: 0.7173, Adjusted R-squared: 0.7093
## F-statistic: 90.4 on 11 and 392 DF, p-value: < 2.2e-16
p_lm <- predict(Boston_lm)
In_sample_ASE<-mean((Boston_train$medv - p_lm)^2)
MSE<- (sum((Boston_train$medv - p_lm)^2)/(dim(Boston_train)[1]-11-1))
#Out of sample performance
p_lm_test <- predict(Boston_lm, newdata = Boston_test)
MSPE_out_of_sample <- mean((Boston_test$medv - p_lm_test)^2)
##linear Model:
In_sample_ASE
## [1] 23.11322
MSE
## [1] 23.82076
MSPE_out_of_sample
## [1] 17.82005
##**cross validation**: To comparison in terms of MSPE is more fair, Less subject to the Randomness (boot package used for cross validation)
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
## split data into folds
boston_glm <- glm(medv~., data = Boston)
cv5 <- cv.glm(boston_glm, data = Boston, K=5)$delta[2]
##split the data into n folds
cv<- cv.glm(boston_glm, data = Boston, K=dim(Boston)[1])$delta[2]
cv5
## [1] 23.89094
cv
## [1] 23.72388
##**cross validation**:
## split data into folds
boston_glm <- glm(medv~., data = Boston)
cv5 <- cv.glm(boston_glm, data = Boston, K=5)$delta[2]
##split the data into n folds
cv<- cv.glm(boston_glm, data = Boston, K=dim(Boston)[1])$delta[2]
cv5
## [1] 24.23142
cv
## [1] 23.72388
##if we run the model again cv5 changes, but cv remains same.
##Regression Tree
## rpart with default cp=0.01
Boston_rpart <- rpart(formula = medv ~ ., data = Boston_train)
prp(Boston_rpart,digits = 4, extra = 1)
## rpart with small cp for bushy tree and then prune using plotcp
Boston_largetree <- rpart(formula = medv ~ ., data = Boston_train, cp = 0.001)
prp(Boston_largetree,digits = 4, extra = 1)
plotcp(Boston_largetree)
# choose the leftmost value for which the value lies below the horizontal line
Boston_rpart <- prune(Boston_largetree, cp=0.0078)
prp(Boston_rpart,digits = 4, extra = 1)
##ASE and MSPE after pruing the model
Boston_train_pred_tree = predict(Boston_rpart)
ASE.rpart<-mean((Boston_train_pred_tree - Boston_train$medv)^2)
Boston_test_pred_tree = predict(Boston_rpart,Boston_test)
mspe.rpart<-mean((Boston_test_pred_tree - Boston_test$medv)^2)
ASE.rpart
## [1] 15.25867
mspe.rpart
## [1] 16.88838
##k-NN with optimal k
##knn for classification
library(FNN)
## Warning: package 'FNN' was built under R version 4.3.2
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
train.norm <- Boston_train
test.norm <- Boston_test
## normalize numerical predictors to 0-1 scale
## for testing and training dataset
## range [0,1]-standardization ##
cols <- colnames(train.norm[, -14]) #scaling only on p=13 predictors X
for (j in cols) {
train.norm[[j]] <- (train.norm[[j]] - min(Boston_train[[j]])) / (max(Boston_train[[j]]) - min(Boston_train[[j]]))
test.norm[[j]] <- (test.norm[[j]] - min(Boston_train[[j]])) / (max(Boston_train[[j]]) - min(Boston_train[[j]]))
}
## Function scale() may be still used for standardization without using a loop. Please make sure that you are using the scaling parameters from TRAING data only ##
#compute the statistics of scaled train and test data
summary(train.norm)
## crim zn indus chas
## Min. :0.0000000 Min. :0.000 Min. :0.0000 Min. :0.00000
## 1st Qu.:0.0008162 1st Qu.:0.000 1st Qu.:0.1695 1st Qu.:0.00000
## Median :0.0026273 Median :0.000 Median :0.3383 Median :0.00000
## Mean :0.0367664 Mean :0.125 Mean :0.3878 Mean :0.07178
## 3rd Qu.:0.0376873 3rd Qu.:0.200 3rd Qu.:0.6466 3rd Qu.:0.00000
## Max. :1.0000000 Max. :1.000 Max. :1.0000 Max. :1.00000
## nox rm age dis
## Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.00000
## 1st Qu.:0.1296 1st Qu.:0.4508 1st Qu.:0.3950 1st Qu.:0.08714
## Median :0.3086 Median :0.5109 Median :0.7590 Median :0.19184
## Mean :0.3483 Mean :0.5265 Mean :0.6631 Mean :0.24629
## 3rd Qu.:0.4918 3rd Qu.:0.5893 3rd Qu.:0.9361 3rd Qu.:0.37517
## Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.00000
## rad tax ptratio black
## Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1304 1st Qu.:0.1718 1st Qu.:0.4468 1st Qu.:0.9489
## Median :0.1739 Median :0.2729 Median :0.6489 Median :0.9875
## Mean :0.3614 Mean :0.4152 Mean :0.6087 Mean :0.9139
## 3rd Qu.:0.4783 3rd Qu.:0.9141 3rd Qu.:0.8085 3rd Qu.:0.9984
## Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
## lstat medv
## Min. :0.0000 Min. : 5.00
## 1st Qu.:0.1338 1st Qu.:17.77
## Median :0.2523 Median :21.70
## Mean :0.2931 Mean :23.02
## 3rd Qu.:0.4076 3rd Qu.:26.25
## Max. :1.0000 Max. :50.00
summary(test.norm)
## crim zn indus chas
## Min. :0.0001018 Min. :0.00000 Min. :0.03372 Min. :0.00000
## 1st Qu.:0.0009933 1st Qu.:0.00000 1st Qu.:0.19795 1st Qu.:0.00000
## Median :0.0039148 Median :0.00000 Median :0.34604 Median :0.00000
## Mean :0.0555069 Mean :0.06863 Mean :0.40558 Mean :0.05882
## 3rd Qu.:0.0561921 3rd Qu.:0.00000 3rd Qu.:0.64663 3rd Qu.:0.00000
## Max. :0.5746830 Max. :0.90000 Max. :1.00000 Max. :1.00000
## nox rm age dis
## Min. :0.01852 Min. :0.1836 Min. :0.0381 Min. :0.004056
## 1st Qu.:0.15329 1st Qu.:0.4356 1st Qu.:0.5247 1st Qu.:0.090478
## Median :0.31481 Median :0.4886 Median :0.8023 Median :0.177295
## Mean :0.35278 Mean :0.5034 Mean :0.7289 Mean :0.226899
## 3rd Qu.:0.55144 3rd Qu.:0.5537 3rd Qu.:0.9475 3rd Qu.:0.320697
## Max. :0.79218 Max. :0.9224 Max. :1.0000 Max. :0.735962
## rad tax ptratio black
## Min. :0.0000 Min. :0.001908 Min. :0.04255 Min. :-0.005578
## 1st Qu.:0.1304 1st Qu.:0.186546 1st Qu.:0.61702 1st Qu.: 0.887374
## Median :0.1739 Median :0.272901 Median :0.75000 Median : 0.982872
## Mean :0.4126 Mean :0.450082 Mean :0.67939 Mean : 0.835058
## 3rd Qu.:1.0000 3rd Qu.:0.914122 3rd Qu.:0.80851 3rd Qu.: 0.997826
## Max. :1.0000 Max. :1.000000 Max. :0.91489 Max. : 1.000000
## lstat medv
## Min. :0.03339 Min. : 5.00
## 1st Qu.:0.17646 1st Qu.:13.95
## Median :0.29484 Median :19.75
## Mean :0.33450 Mean :20.62
## 3rd Qu.:0.45054 3rd Qu.:23.90
## Max. :0.97268 Max. :50.00
summary(train.norm$rm)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0000 0.4508 0.5109 0.5265 0.5893 1.0000
summary(train.norm$lstat)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0000 0.1338 0.2523 0.2931 0.4076 1.0000
summary(test.norm$rm)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.1836 0.4356 0.4886 0.5034 0.5537 0.9224
summary(test.norm$lstat)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.03339 0.17646 0.29484 0.33450 0.45054 0.97268
#in-sample
Boston.knn.train <- knn.reg(train = train.norm[, 1:13],
test = train.norm[, 1:13],
y = train.norm$medv,
k = 5)
Boston.knn.train <- data.frame(cbind(pred = Boston.knn.train$pred, actual=train.norm$medv))
#calculate in-sample ASE
ASE<-sum((Boston_train$medv-Boston.knn.train$pred)^2)/length(Boston_train$medv)
ASE
## [1] 15.05862
Boston.knn.reg <- knn.reg(train = train.norm[, 1:13],
test = test.norm[, 1:13],
y = train.norm$medv,
k = 5)
# compute the actual and predicted values and view the first 20 records
Boston.results <- data.frame(cbind(pred = Boston.knn.reg$pred, actual = Boston_test$medv))
# Out-of-Sample Testing
# calculate MSPE (root mean (average) sum squared prediction errors)
MSPE <- sum((Boston_test$medv-Boston.results$pred)^2)/length(Boston_test$medv)
MSPE
## [1] 17.93792
#Select the best k
##################
set.seed(15848936)
sample_index2 <- sample(nrow(Boston_train),nrow(Boston_train)*0.80)
train2.norm <- train.norm[sample_index2,]
valid.norm <- train.norm[-sample_index2,]
# initialize a data frame with two columns: k and accuracy
RMSE.df <- data.frame(k = seq(1, 30, 1), RMSE.k = rep(0, 30))
# compute knn for different k on validation set
for (i in 1:30) {
knn.reg.pred <- knn.reg(train = train2.norm[, c(1:13)], test = valid.norm[, c(1:13)],
y = train2.norm$medv, k = i)
RMSE.df[i, 2] <- sqrt(sum((valid.norm$medv-knn.reg.pred$pred)^2)/length(valid.norm$medv))
}
RMSE.df
k <- which(RMSE.df[,2] == min(RMSE.df[,2]))
##Optimal K
k
## [1] 5
#in-sample
Boston.knn.train.best.k <- knn.reg(train = train.norm[, 1:13],
test = train.norm[, 1:13],
y = train.norm$medv,
k = 5)
Boston.knn.best.k <- data.frame(cbind(pred = Boston.knn.train.best.k$pred, actual=train.norm$medv))
#calculate in-sample ASE
ASE<-sum((Boston_train$medv-Boston.knn.best.k$pred)^2)/length(Boston_train$medv)
Boston.knn.reg <- knn.reg(train = train.norm[, 1:13],
test = test.norm[, 1:13],
y = train.norm$medv,
k = 5)
Boston.results <- data.frame(cbind(pred = Boston.knn.reg$pred, actual = Boston_test$medv))
# Out-of-Sample Testing
# calculate MSPE (root mean (average) sum squared prediction errors)
MSPE <- sum((Boston_test$medv-Boston.results$pred)^2)/length(Boston_test$medv)
##Model knn results For optimal K =5
##ASE
ASE
## [1] 15.05862
##MSPE
MSPE
## [1] 17.93792
##Random Forests
library(randomForest)
## Warning: package 'randomForest' was built under R version 4.3.3
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
Boston_rf <- randomForest(medv~.,
data = Boston_train, importance = TRUE)
#Make prediction on training sample
Boston_rf_pred_train<- predict(Boston_rf, Boston_train)
mean((Boston_train$medv-Boston_rf_pred_train)^2)
## [1] 2.271846
# in-sample ASE (average/mean squared residuals) = 2.2718 by default
#check variable importance
Boston_rf$importance #rm and lstat are top 2
## %IncMSE IncNodePurity
## crim 8.0562285 2006.5178
## zn 0.6230269 338.1159
## indus 6.6178477 2097.3390
## chas 0.4507812 144.8626
## nox 8.6715440 2018.8596
## rm 33.5916404 9066.8001
## age 4.1357630 1032.5357
## dis 7.1259865 2190.6192
## rad 1.4931670 261.7385
## tax 3.8282024 1096.7462
## ptratio 5.8370685 1770.4934
## black 1.2844821 589.3379
## lstat 57.0878785 9621.7533
# plot out of bag (OOB) errors for each ntree value from 1 to 500
plot(Boston_rf$mse, type='l', col=2, lwd=2, xlab = "ntree", ylab = "OOB Error")
Boston_rf_pred<- predict(Boston_rf, Boston_test)
mean((Boston_test$medv-Boston_rf_pred)^2)
## [1] 7.969715
#MSPE is 7.9697 for test data
##Boosting
library(gbm)
## Warning: package 'gbm' was built under R version 4.3.3
## Loaded gbm 2.1.9
## This version of gbm is no longer under development. Consider transitioning to gbm3, https://github.com/gbm-developers/gbm3
Boston_boost<- gbm(formula = medv~.,
data = Boston_train,
distribution = "gaussian",
n.trees = 100,
shrinkage = 0.1,
interaction.depth = 1) #boosting with defaults
summary(Boston_boost)
#In-sample prediction using Boosting tree
Boston_boost_pred_train<- predict(Boston_boost, Boston_train, n.trees = 100) #use default setting
mean((Boston_train$medv-Boston_boost_pred_train)^2) #In-sample ASE = 12.42303
## [1] 12.42303
#OUT-of-sample prediction using Boosting tree
Boston_boost_pred_test<- predict(Boston_boost, Boston_test, n.trees = 100)
mean((Boston_test$medv-Boston_boost_pred_test)^2) #out-of-sample MSPE = 9.412584
## [1] 9.412584
##Generalized Additive Model
library(randomForest)
library(xgboost)
## Warning: package 'xgboost' was built under R version 4.3.3
library(nlme)
library(mgcv)
## This is mgcv 1.8-42. For overview type 'help("mgcv-package")'.
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
Boston_gam <- gam(medv ~ s(crim)+s(zn)+s(indus)+chas+s(nox)
+s(rm)+s(age)+s(dis)+rad+s(tax)+s(ptratio)
+s(black)+s(lstat),data=Boston_train)
summary(Boston_gam)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## medv ~ s(crim) + s(zn) + s(indus) + chas + s(nox) + s(rm) + s(age) +
## s(dis) + rad + s(tax) + s(ptratio) + s(black) + s(lstat)
##
## Parametric coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 21.7363 1.3470 16.137 <2e-16 ***
## chas 0.3867 0.7005 0.552 0.581
## rad 0.1344 0.1436 0.936 0.350
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df F p-value
## s(crim) 7.704 8.522 7.845 < 2e-16 ***
## s(zn) 1.000 1.000 2.685 0.10218
## s(indus) 4.028 4.911 4.029 0.00307 **
## s(nox) 8.809 8.978 15.517 < 2e-16 ***
## s(rm) 5.756 6.939 22.075 < 2e-16 ***
## s(age) 1.000 1.000 0.636 0.42563
## s(dis) 8.915 8.995 9.176 < 2e-16 ***
## s(tax) 6.435 7.474 7.166 < 2e-16 ***
## s(ptratio) 1.224 1.407 24.764 1.25e-07 ***
## s(black) 2.339 2.889 2.440 0.08158 .
## s(lstat) 6.823 7.937 20.781 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.875 Deviance explained = 89.2%
## GCV = 11.919 Scale est. = 10.236 n = 404
plot(Boston_gam, shade=TRUE, seWithMean=TRUE, scale=0, pages=1)
#refit gam on Boston training (nonlinear to linear),
##removing zn, age, ptratio variables from non linearity because the edf is 1 approx
Boston_gam_re <- gam(medv ~ s(crim)+zn+s(indus)+chas+s(nox)
+s(rm)+age+s(dis)+rad+s(tax)+ptratio
+s(black)+s(lstat),data=Boston_train)
summary(Boston_gam_re)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## medv ~ s(crim) + zn + s(indus) + chas + s(nox) + s(rm) + age +
## s(dis) + rad + s(tax) + ptratio + s(black) + s(lstat)
##
## Parametric coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 36.123739 3.088084 11.698 < 2e-16 ***
## zn 0.025936 0.015578 1.665 0.0968 .
## chas 0.386755 0.700650 0.552 0.5813
## age -0.009996 0.012513 -0.799 0.4249
## rad 0.129829 0.143131 0.907 0.3650
## ptratio -0.763947 0.130976 -5.833 1.25e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df F p-value
## s(crim) 7.670 8.505 7.855 < 2e-16 ***
## s(indus) 4.008 4.891 4.063 0.00314 **
## s(nox) 8.826 8.982 15.673 < 2e-16 ***
## s(rm) 5.811 6.995 22.287 < 2e-16 ***
## s(dis) 8.897 8.994 9.084 < 2e-16 ***
## s(tax) 6.430 7.475 7.174 < 2e-16 ***
## s(black) 2.355 2.910 2.430 0.08089 .
## s(lstat) 6.825 7.939 20.735 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.875 Deviance explained = 89.2%
## GCV = 11.921 Scale est. = 10.244 n = 404
plot(Boston_gam_re, shade=TRUE, seWithMean=TRUE, scale=0, pages=1)
#refit gam on Boston training (remove nonsignificant variables)
Boston_gam_final <- gam(medv ~ s(crim)+s(indus)+s(nox)
+s(rm)+s(dis)+s(tax)+ptratio
+s(lstat),data=Boston_train)
summary(Boston_gam_final)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## medv ~ s(crim) + s(indus) + s(nox) + s(rm) + s(dis) + s(tax) +
## ptratio + s(lstat)
##
## Parametric coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 38.5506 2.3458 16.434 < 2e-16 ***
## ptratio -0.8479 0.1277 -6.638 1.2e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df F p-value
## s(crim) 7.484 8.381 8.021 <2e-16 ***
## s(indus) 3.964 4.821 4.443 0.0013 **
## s(nox) 8.861 8.988 15.794 <2e-16 ***
## s(rm) 5.685 6.868 23.238 <2e-16 ***
## s(dis) 8.898 8.995 10.136 <2e-16 ***
## s(tax) 6.743 7.750 7.061 <2e-16 ***
## s(lstat) 6.738 7.866 26.838 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## R-sq.(adj) = 0.872 Deviance explained = 88.8%
## GCV = 11.951 Scale est. = 10.461 n = 404
plot(Boston_gam_final, shade=TRUE, seWithMean=TRUE, scale=0, pages=1)
#In-sample fit performance
#Average Sum of Squared Error
Boston_gam.mse.ori <- Boston_gam$dev/nrow(Boston_train) #original model
Boston_gam.mse.adj <- Boston_gam_re$dev/nrow(Boston_train) #adjusted model
Boston_gam.mse.train <- Boston_gam_final$dev/nrow(Boston_train) #final model
Boston_gam.mse.ori;Boston_gam.mse.adj;Boston_gam.mse.train
## [1] 8.791109
## [1] 8.803315
## [1] 9.156565
#using the predict() function
Pred_gam_ori <- predict(Boston_gam,Boston_train)#final model
mean((Pred_gam_ori - Boston_train$medv)^2)
## [1] 8.791109
Pred_gam_adj <- predict(Boston_gam_re,Boston_train)#final model
mean((Pred_gam_adj - Boston_train$medv)^2)
## [1] 8.803315
Pred_gam_train <- predict(Boston_gam_final,Boston_train)#final model
mean((Pred_gam_train - Boston_train$medv)^2)
## [1] 9.156565
#out of sample performance
Pred_gam_ori_test <- predict(Boston_gam,Boston_test)#final model
mean((Pred_gam_ori_test - Boston_test$medv)^2)
## [1] 9.830322
Pred_gam_adj_test <- predict(Boston_gam_re, Boston_test)#final model
mean((Pred_gam_adj_test - Boston_test$medv)^2)
## [1] 9.863091
Pred_gam_test <- predict(Boston_gam_final,Boston_test)
mean((Pred_gam_test - Boston_test$medv)^2)
## [1] 9.49374
#AIC
AIC(Boston_gam);AIC(Boston_gam_re);AIC(Boston_gam_final)
## [1] 2140.759
## [1] 2140.899
## [1] 2143.894
##Neural Networks
library(neuralnet)
## Warning: package 'neuralnet' was built under R version 4.3.3
set.seed(15848936)
sample_index <- sample(nrow(Boston),nrow(Boston)*0.80)
Boston_train <- Boston[sample_index,]
Boston_test <- Boston[-sample_index,]
p= dim(Boston)[2]-1
#### Neural networks on (unscaled) original Training data and plot ####
f <- as.formula("medv ~ .")
nn_unscaled <- neuralnet(f,data=Boston_train, hidden=c(5,3), linear.output=T)
summary(nn_unscaled)
## Length Class Mode
## call 5 -none- call
## response 404 -none- numeric
## covariate 5252 -none- numeric
## model.list 2 -none- list
## err.fct 1 -none- function
## act.fct 1 -none- function
## linear.output 1 -none- logical
## data 14 data.frame list
## exclude 0 -none- NULL
## net.result 1 -none- list
## weights 1 -none- list
## generalized.weights 1 -none- list
## startweights 1 -none- list
## result.matrix 95 -none- numeric
plot(nn_unscaled)
# in-sample fit (prediction) # ASE = 81.74783
yhat.train <- predict(object = nn_unscaled, newdata = Boston_train)
ASE_nn <- sum((Boston_train$medv - yhat.train)^2)/nrow(Boston_train)
ASE_nn
## [1] 81.74783
#### MSPE of the above neural network model for Testing data####
## MSPE = 89.1568
pr_nn <- compute(nn_unscaled, Boston_test[,1:p])
MSPE_nn <- sum((Boston_test$medv - pr_nn$net.result)^2)/nrow(Boston_test) ## MSPE of testing set ##
MSPE_nn
## [1] 96.15683
## initialize scaling training, testing, and new data frames to originals ##
train.norm <- Boston_train
test.norm <- Boston_test
summary(train.norm)
## crim zn indus chas
## Min. : 0.00632 Min. : 0.0 Min. : 0.460 Min. :0.00000
## 1st Qu.: 0.07894 1st Qu.: 0.0 1st Qu.: 5.085 1st Qu.:0.00000
## Median : 0.24008 Median : 0.0 Median : 9.690 Median :0.00000
## Mean : 3.27742 Mean : 12.5 Mean :11.039 Mean :0.07178
## 3rd Qu.: 3.35936 3rd Qu.: 20.0 3rd Qu.:18.100 3rd Qu.:0.00000
## Max. :88.97620 Max. :100.0 Max. :27.740 Max. :1.00000
## nox rm age dis
## Min. :0.3850 Min. :3.561 Min. : 2.90 Min. : 1.130
## 1st Qu.:0.4480 1st Qu.:5.914 1st Qu.: 41.25 1st Qu.: 2.088
## Median :0.5350 Median :6.228 Median : 76.60 Median : 3.239
## Mean :0.5543 Mean :6.309 Mean : 67.29 Mean : 3.838
## 3rd Qu.:0.6240 3rd Qu.:6.637 3rd Qu.: 93.80 3rd Qu.: 5.255
## Max. :0.8710 Max. :8.780 Max. :100.00 Max. :12.127
## rad tax ptratio black
## Min. : 1.000 Min. :187.0 Min. :12.60 Min. : 2.52
## 1st Qu.: 4.000 1st Qu.:277.0 1st Qu.:16.80 1st Qu.:376.74
## Median : 5.000 Median :330.0 Median :18.70 Median :391.95
## Mean : 9.312 Mean :404.5 Mean :18.32 Mean :362.94
## 3rd Qu.:12.000 3rd Qu.:666.0 3rd Qu.:20.20 3rd Qu.:396.29
## Max. :24.000 Max. :711.0 Max. :22.00 Max. :396.90
## lstat medv
## Min. : 1.730 Min. : 5.00
## 1st Qu.: 6.577 1st Qu.:17.77
## Median :10.875 Median :21.70
## Mean :12.350 Mean :23.02
## 3rd Qu.:16.500 3rd Qu.:26.25
## Max. :37.970 Max. :50.00
summary(test.norm)
## crim zn indus chas
## Min. : 0.01538 Min. : 0.000 Min. : 1.38 Min. :0.00000
## 1st Qu.: 0.09470 1st Qu.: 0.000 1st Qu.: 5.86 1st Qu.:0.00000
## Median : 0.35462 Median : 0.000 Median : 9.90 Median :0.00000
## Mean : 4.94476 Mean : 6.863 Mean :11.52 Mean :0.05882
## 3rd Qu.: 5.00572 3rd Qu.: 0.000 3rd Qu.:18.10 3rd Qu.:0.00000
## Max. :51.13580 Max. :90.000 Max. :27.74 Max. :1.00000
## nox rm age dis
## Min. :0.3940 Min. :4.519 Min. : 6.60 Min. :1.174
## 1st Qu.:0.4595 1st Qu.:5.835 1st Qu.: 53.85 1st Qu.:2.125
## Median :0.5380 Median :6.111 Median : 80.80 Median :3.079
## Mean :0.5565 Mean :6.188 Mean : 73.67 Mean :3.625
## 3rd Qu.:0.6530 3rd Qu.:6.450 3rd Qu.: 94.90 3rd Qu.:4.656
## Max. :0.7700 Max. :8.375 Max. :100.00 Max. :9.223
## rad tax ptratio black
## Min. : 1.00 Min. :188.0 Min. :13.00 Min. : 0.32
## 1st Qu.: 4.00 1st Qu.:284.8 1st Qu.:18.40 1st Qu.:352.48
## Median : 5.00 Median :330.0 Median :19.65 Median :390.14
## Mean :10.49 Mean :422.8 Mean :18.99 Mean :331.85
## 3rd Qu.:24.00 3rd Qu.:666.0 3rd Qu.:20.20 3rd Qu.:396.04
## Max. :24.00 Max. :711.0 Max. :21.20 Max. :396.90
## lstat medv
## Min. : 2.940 Min. : 5.00
## 1st Qu.: 8.125 1st Qu.:13.95
## Median :12.415 Median :19.75
## Mean :13.852 Mean :20.62
## 3rd Qu.:18.058 3rd Qu.:23.90
## Max. :36.980 Max. :50.00
## normalize all numerical variables (X&Y) to 0-1 scale, range [0,1]-standardization ##
cols <- colnames(train.norm[, ]) #scaling both X and Y
for (j in cols) {
train.norm[[j]] <- (train.norm[[j]] - min(Boston_train[[j]])) / (max(Boston_train[[j]]) - min(Boston_train[[j]]))
test.norm[[j]] <- (test.norm[[j]] - min(Boston_train[[j]])) / (max(Boston_train[[j]]) - min(Boston_train[[j]]))
}
#### Neural networks on (scaled) Training data and plot ####
set.seed(15848936)
nn_scaled <- neuralnet(f,data=train.norm, hidden=c(5,3), linear.output=T)
plot(nn_scaled)
# in-sample fit (prediction) # ASE = 4.4869
pr_nn_scaled_train <- compute(nn_scaled, train.norm[,1:p])
## recover the predicted value back to the original response scale ##
pr_nn_org <- pr_nn_scaled_train$net.result*(max(Boston_train$medv)-min(Boston_train$medv))+min(Boston_train$medv)
train_r <- (train.norm$medv)*(max(Boston_train$medv)-min(Boston_train$medv))+min(Boston_train$medv)
ase.norm<-mean((train_r - pr_nn_org)^2) ##in-sample average sum squared error
ase.norm
## [1] 4.486885
#### MSPE of the above neural network model for Testing data####
pr_nn_scaled_test <- compute(nn_scaled, test.norm[,1:p])
pr_nn_org_t <- pr_nn_scaled_test$net.result*(max(Boston_train$medv)-min(Boston_train$medv))+min(Boston_train$medv)
test_r <- (test.norm$medv)*(max(Boston_train$medv)-min(Boston_train$medv))+min(Boston_train$medv)
mean((test_r - pr_nn_org_t)^2)
## [1] 11.09675
## MSPE of testing set = 11.09675