1. 目的:根據房子信息,判斷博士頓地區的房價。
2. 數據來源:論文《Hedonic housing prices and the demand for clean air》,數據中共含506個觀測值,及16個變量。其中,每個觀測值代表一個人口普查區。
boston <- read.csv("boston.csv") # 讀取文件
str(boston) # 查看數據結構
3. 變量介紹:
(1)town:每一個人口普查區所在的城鎮
(2)LON: 人口普查區中心的經度
(3)LAT: 人口普查區中心的緯度
(4)MEDV: 每一個人口普查區所對應的房子價值的中位數 (單位為$1000)
(5)CRIM: 人均犯罪率
(6)ZN: 土地中有多少是地區是大量住宅物業
(7)INDUS: 區域中用作工業用途的土地占比
(8)CHAS: 1:該人口普查區緊鄰查爾斯河;0: 該人口普查區沒有緊鄰查爾斯河
(9)NOX: 空氣中氮氧化物的集中度 (衡量空氣污染的指標)
(10)RM: 每個房子的平均房間數目
(11)AGE: 建於1940年以前的房子的比例
(12)DIS: 該人口普查區距離波士頓市中心的距離
(13)RAD: 距離重要高速路的遠近程度 (1代表最近;24代表最遠)
(14)TAX: 房子每$10,000價值所對應的稅收金額
(15)PTRATIO: 該城鎮學生與老師的比例
View(boston) # 查看數據
4. 應用及分析
4.1 數據探索
plot(boston$LON, boston$LAT) # 根據人口普查區的經度和緯度作圖
points(boston$LON[boston$CHAS == 1], boston$LAT[boston$CHAS==1], col = 'blue', pch = 19) # 藍色代表緊鄰查爾斯河的人口普查區
summary(boston$NOX) # NOX的平均數大約為0.55 points(boston$LON[boston$NOX >= 0.55], boston$LAT[boston$NOX >= 0.55], col = 'gray', pch = 19) # 灰色代表NOX大於平均值的地區
summary(boston$MEDV) #各地區中位數房價 的 中位數為21.2 points(boston$LON[boston$MEDV >= 21.2], boston$LAT[boston$MEDV >= 21.2], col = 'green', pch = 19) # 綠色代表中位數房價 高於中位數的地區
4.2 運用經度和緯度兩個自變量構建線性回歸模型
model1 <- lm(MEDV ~ LON + LAT, data = boston) # 經度和緯度為自變量,中位數房價為因變量 summary(model1) # not a good model
雖然自變量“緯度”非常顯著,但是模型的調整后R^2只有0.1036,因此,線性回歸模型不是非常理想。
plot(boston$LON, boston$LAT) points(boston$LON[boston$MEDV >= 21.2], boston$LAT[boston$MEDV >= 21.2], col = 'green', pch = 19) # 綠色代表實際房價中位數 高於中位數的地區
points(boston$LON[model1$fitted.values >= 21.2], boston$LAT[model1$fitted.values >= 21.2], col = 'yellow', pch = 19) # 黃色代表線性回歸模型所預測的中位數房價 高於 中位數的地區
上圖進一步證實了線性回歸模型不是很理想,因為模型完全忽略了圖像中右半部分的地區。同時,這也證實了“自變量’緯度'不顯著”的說法。
4.3 運用經度和緯度兩個自變量構建CART回歸樹
library(rpart) # 加載rpart包,用於構建CART模型 library(rpart.plot) # 加載rpart.plot包,用於繪制回歸樹 tree1 <- rpart(MEDV ~ LAT + LON, data = boston) # 不需要加method="class",因為構建的是回歸樹而非分類樹 prp(tree1, digits = 4) # 繪制回歸樹
points(boston$LON[boston$MEDV >= 21.2], boston$LAT[boston$MEDV >= 21.2], col = 'green', pch = 19) # 綠色為原數據中房價中位數 高於 中位數的 地區
fitted <- predict(tree1) # 運用回歸樹tree1預測每個地區的房價中位數 points(boston$LON[fitted >= 21.2], boston$LAT[fitted >= 21.2], col = 'yellow', pch = 19) # 黃色為預測數據高於中位數的地區
由此不難看出,與線性回歸模型相比,回歸樹tree1的准確性顯著提高。
4.4 運用全部自變量構建線性回歸模型並不斷優化
library(caTools) # 加載caTools包,將數據分為70%訓練集和30%測試集 set.seed(123) # 設置種子 spl <- sample.split(boston$MEDV, SplitRatio = 0.7) train <- subset(boston, spl == T) # 訓練集 test <- subset(boston, spl == F) # 測試集
lm1 <- lm(MEDV ~ LAT + LON + CRIM + ZN + INDUS + CHAS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO, data = train) # 運用訓練集數據構建線性回歸模型 summary(lm1)
其中,CRIM, CHAS, NOX, RM, AGE, DIS, RAD, TAX, PTRATIO為顯著變量,模型調整后R^2為0.6525,較之前線性回歸模型的調整后R^2相比顯著提高。
lm1pred <- predict(lm1, newdata = test) # 將模型應用到測試集用於預測集
library(forecast) # 加載forecast包
accuracy(lm1pred, test$MEDV) # 計算模型准確性
接着,依次剔除模型中最不顯著的自變量LAT, INDUS, LON,直至所有自變量均顯著,構建以下線性回歸模型:
lm4 <- lm(MEDV ~ CRIM + ZN + CHAS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO, data = train) # 將模型應用到測試集用於預測集
summary(lm4) lm4pred <- predict(lm4, newdata = test)
accuracy(lm4pred, test$MEDV)
對比兩個模型的准確性:
library(forecast) accuracy(lm1pred, test$MEDV) # 應用所有自變量的模型准確性 (模型4) accuracy(lm4pred, test$MEDV) # 剔除LAT, INDUS, LON以后的模型准確性 (模型1)
對比ME, RMSE, MAE, MPE, MAPE, 不難發現模型4略微比模型1准確。
4.5 運用全部自變量構建CART回歸樹並不斷優化
tree3 <- rpart(MEDV ~ LAT + LON + CRIM + ZN + INDUS + CHAS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO, data = train) prp(tree3)
treepred <- predict(tree3, newdata = test) # 將回歸樹tree3應用到訓練集,進行預測 accuracy(treepred, test$MEDV) # 回歸樹tree3的准確性
通過對比ME, RMSE, MAE, MPE, MAPE等指標,發現該回歸樹tree3的准確定略低於線性回歸模型 (模型1以及模型4)
接下來,通過引入cp, 進行交叉檢驗來尋找最佳的回歸樹模型
library(caret) library(lattice) library(ggplot2) library(e1071) tr.control <- trainControl(method = 'cv', number = 10) cp.grid <- expand.grid(.cp = (0:10)*0.001) tr <- train(MEDV ~ LAT + LON + CRIM + ZN + INDUS + CHAS + NOX + RM + AGE + DIS + TAX + PTRATIO, data = train, method = 'rpart', trControl = tr.control, tuneGrid = cp.grid) tr # cp = 0.001
基於cp=0.001,構建新的回歸樹
best.tree <- tr$finalModel prp(best.tree)
best.tree.pred <- predict(best.tree, newdata = test) # 將新的回歸樹best.tree應用到訓練集數據中進行預測 accuracy(best.tree.pred, test$MEDV) # 回歸樹best.tree的准確性
雖然引入cp,做了交叉檢驗以后,回歸樹best.tree與回歸樹tree3相比,准確率有所提升,但准確率仍低於線性回歸模型(模型4)。因此,回歸樹模型不一定是一個更好的選擇。