Kaggle實戰(2)—房價預測:高階回歸技術應用
本文數據來自Kaggle,是Kaggle新手入門的第二個項目:房價預測。競賽鏈接如下:
House Prices: Advanced Regression Techniques
競賽給了已經成交的近1500座房子的80個特徵,然後讓我們根據這些特徵來預測房子的銷售價格。
被預測變數與Titanic 生存預測不同,是一個連續型變數。通常數據分析主要有兩類問題,一類是分類,就好比隨機森林——二元分類的利器之Kaggle初體驗Titanic: Machine Learning from Disaster 中的生存預測,結果有兩種可能,分類問題一般針對離散型變數;另外一類是回歸(regression),當然,回歸也可以用於預測離散型變數,本次數據分析所用到的主要是針對連續型變數。
1 載入數據
#數據導入n> train <- read.csv(train.csv,stringsAsFactors = T)n> test <- read.csv(test.csv,stringsAsFactors = T)n
為了後面便於建模,在read.csv()函數當中指定參數「stringsAsFactors = T」將所有數值型變數轉換為因子型。
初步觀察數據:
> head(train)n Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities LotConfig LandSlopen1 1 60 RL 65 8450 Pave <NA> Reg Lvl AllPub Inside Gtln2 2 20 RL 80 9600 Pave <NA> Reg Lvl AllPub FR2 Gtln3 3 60 RL 68 11250 Pave <NA> IR1 Lvl AllPub Inside Gtln4 4 70 RL 60 9550 Pave <NA> IR1 Lvl AllPub Corner Gtln5 5 60 RL 84 14260 Pave <NA> IR1 Lvl AllPub FR2 Gtln6 6 50 RL 85 14115 Pave <NA> IR1 Lvl AllPub Inside Gtln Neighborhood Condition1 Condition2 BldgType HouseStyle OverallQual OverallCond YearBuilt YearRemodAdd RoofStylen1 CollgCr Norm Norm 1Fam 2Story 7 5 2003 2003 Gablen2 Veenker Feedr Norm 1Fam 1Story 6 8 1976 1976 Gablen3 CollgCr Norm Norm 1Fam 2Story 7 5 2001 2002 Gablen4 Crawfor Norm Norm 1Fam 2Story 7 5 1915 1970 Gablen5 NoRidge Norm Norm 1Fam 2Story 8 5 2000 2000 Gablen6 Mitchel Norm Norm 1Fam 1.5Fin 5 5 1993 1995 Gablen RoofMatl Exterior1st Exterior2nd MasVnrType MasVnrArea ExterQual ExterCond Foundation BsmtQual BsmtCondn1 CompShg VinylSd VinylSd BrkFace 196 Gd TA PConc Gd TAn2 CompShg MetalSd MetalSd None 0 TA TA CBlock Gd TAn3 CompShg VinylSd VinylSd BrkFace 162 Gd TA PConc Gd TAn4 CompShg Wd Sdng Wd Shng None 0 TA TA BrkTil TA Gdn5 CompShg VinylSd VinylSd BrkFace 350 Gd TA PConc Gd TAn6 CompShg VinylSd VinylSd None 0 TA TA Wood Gd TAn BsmtExposure BsmtFinType1 BsmtFinSF1 BsmtFinType2 BsmtFinSF2 BsmtUnfSF TotalBsmtSF Heating HeatingQC CentralAirn1 No GLQ 706 Unf 0 150 856 GasA Ex Yn2 Gd ALQ 978 Unf 0 284 1262 GasA Ex Yn3 Mn GLQ 486 Unf 0 434 920 GasA Ex Yn4 No ALQ 216 Unf 0 540 756 GasA Gd Yn5 Av GLQ 655 Unf 0 490 1145 GasA Ex Yn6 No GLQ 732 Unf 0 64 796 GasA Ex Yn Electrical X1stFlrSF X2ndFlrSF LowQualFinSF GrLivArea BsmtFullBath BsmtHalfBath FullBath HalfBath BedroomAbvGrn1 SBrkr 856 854 0 1710 1 0 2 1 3n2 SBrkr 1262 0 0 1262 0 1 2 0 3n3 SBrkr 920 866 0 1786 1 0 2 1 3n4 SBrkr 961 756 0 1717 1 0 1 0 3n5 SBrkr 1145 1053 0 2198 1 0 2 1 4n6 SBrkr 796 566 0 1362 1 0 1 1 1n KitchenAbvGr KitchenQual TotRmsAbvGrd Functional Fireplaces FireplaceQu GarageType GarageYrBlt GarageFinishn1 1 Gd 8 Typ 0 <NA> Attchd 2003 RFnn2 1 TA 6 Typ 1 TA Attchd 1976 RFnn3 1 Gd 6 Typ 1 TA Attchd 2001 RFnn4 1 Gd 7 Typ 1 Gd Detchd 1998 Unfn5 1 Gd 9 Typ 1 TA Attchd 2000 RFnn6 1 TA 5 Typ 0 <NA> Attchd 1993 Unfn GarageCars GarageArea GarageQual GarageCond PavedDrive WoodDeckSF OpenPorchSF EnclosedPorch X3SsnPorch ScreenPorchn1 2 548 TA TA Y 0 61 0 0 0n2 2 460 TA TA Y 298 0 0 0 0n3 2 608 TA TA Y 0 42 0 0 0n4 3 642 TA TA Y 0 35 272 0 0n5 3 836 TA TA Y 192 n6 2 480 TA TA Y 40 30 0 320 0n PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleCondition SalePricen1 0 <NA> <NA> <NA> 0 2 2008 WD Normal 208500n2 0 <NA> <NA> <NA> 0 5 2007 WD Normal 181500n3 0 <NA> <NA> <NA> 0 9 2008 WD Normal 223500n4 0 <NA> <NA> <NA> 0 2 2006 WD Abnorml 140000n5 0 <NA> <NA> <NA> 0 12 2008 WD Normal 250000n6 0 <NA> MnPrv Shed 700 10 2009 WD Normal 143000n> head(test)n Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities LotConfig LandSlopen1 1461 20 RH 80 11622 Pave <NA> Reg Lvl AllPub Inside Gtln2 1462 20 RL 81 14267 Pave <NA> IR1 Lvl AllPub Corner Gtln3 1463 60 RL 74 13830 Pave <NA> IR1 Lvl AllPub Inside Gtln4 1464 60 RL 78 9978 Pave <NA> IR1 Lvl AllPub Inside Gtln5 1465 120 RL 43 5005 Pave <NA> IR1 HLS AllPub Inside Gtln6 1466 60 RL 75 10000 Pave <NA> IR1 Lvl AllPub Corner Gtln Neighborhood Condition1 Condition2 BldgType HouseStyle OverallQual OverallCond YearBuilt YearRemodAdd RoofStylen1 NAmes Feedr Norm 1Fam 1Story 5 6 1961 1961 Gablen2 NAmes Norm Norm 1Fam 1Story 6 6 1958 1958 Hipn3 Gilbert Norm Norm 1Fam 2Story 5 5 1997 1998 Gablen4 Gilbert Norm Norm 1Fam 2Story 6 6 1998 1998 Gablen5 StoneBr Norm Norm TwnhsE 1Story 8 5 1992 1992 Gablen6 Gilbert Norm Norm 1Fam 2Story 6 5 1993 1994 Gablen RoofMatl Exterior1st Exterior2nd MasVnrType MasVnrArea ExterQual ExterCond Foundation BsmtQual BsmtCondn1 CompShg VinylSd VinylSd None 0 TA TA CBlock TA TAn2 CompShg Wd Sdng Wd Sdng BrkFace 108 TA TA CBlock TA TAn3 CompShg VinylSd VinylSd None 0 TA TA PConc Gd TAn4 CompShg VinylSd VinylSd BrkFace 20 TA TA PConc TA TAn5 CompShg HdBoard HdBoard None 0 Gd TA PConc Gd TAn6 CompShg HdBoard HdBoard None 0 TA TA PConc Gd TAn BsmtExposure BsmtFinType1 BsmtFinSF1 BsmtFinType2 BsmtFinSF2 BsmtUnfSF TotalBsmtSF Heating HeatingQC CentralAirn1 No Rec 468 LwQ 144 270 882 GasA TA Yn2 No ALQ 923 Unf 0 406 1329 GasA TA Yn3 No GLQ 791 Unf 0 137 928 GasA Gd Yn4 No GLQ 602 Unf 0 324 926 GasA Ex Yn5 No ALQ 263 Unf 0 1017 1280 GasA Ex Yn6 No Unf 0 Unf 0 763 763 GasA Gd Yn Electrical X1stFlrSF X2ndFlrSF LowQualFinSF GrLivArea BsmtFullBath BsmtHalfBath FullBath HalfBath BedroomAbvGrn1 SBrkr 896 0 0 896 0 0 1 0 2n2 SBrkr 1329 0 0 1329 0 0 1 1 3n3 SBrkr 928 701 0 1629 0 0 2 1 3n4 SBrkr 926 678 0 1604 0 0 2 1 3n5 SBrkr 1280 0 0 1280 0 0 2 0 2n6 SBrkr 763 892 0 1655 0 n KitchenAbvGr KitchenQual TotRmsAbvGrd Functional Fireplaces FireplaceQu GarageType GarageYrBlt GarageFinishn1 1 TA 5 Typ 0 <NA> Attchd 1961 Unfn2 1 Gd 6 Typ 0 <NA> Attchd 1958 Unfn3 1 TA 6 Typ 1 TA Attchd 1997 Finn4 1 Gd 7 Typ 1 Gd Attchd 1998 Finn5 1 Gd 5 Typ 0 <NA> Attchd 1992 RFnn6 1 TA 7 Typ 1 TA Attchd 1993 Finn GarageCars GarageArea GarageQual GarageCond PavedDrive WoodDeckSF OpenPorchSF EnclosedPorch X3SsnPorch ScreenPorchn1 1 730 TA TA Y 140 0 0 0 120n2 1 312 TA TA Y 393 36 0 0 0n3 2 482 TA TA Y 212 34 0 0 0n4 2 470 TA TA Y 360 36 0 0 0n5 2 506 TA TA Y 0 82 0 0 144n6 2 440 TA TA Y 157 84 0 0 0n PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleConditionn1 0 <NA> MnPrv <NA> 0 6 2010 WD Normaln2 0 <NA> <NA> Gar2 12500 6 2010 WD Normaln3 0 <NA> MnPrv <NA> 0 3 2010 WD Normaln4 0 <NA> <NA> <NA> 0 6 2010 WD Normaln5 0 <NA> <NA> <NA> 0 1 2010 WD Normaln6 0 <NA> <NA> <NA> 0 4 2010 WD Normaln> n
不難發現,兩個數據集除了需要預測的 SalePrice 欄位有所不同以外,其它欄位均相同,由於後續要對訓練數據和測試數據做相同的轉換,為了避免重複操作和出現不一致的情況,更為了避免可能碰到的Categorical類型新level的問題,這裡建議將兩個數據集合同,統一操作。
合併數據:
#為了能夠使用rbind()將test 缺失列補齊n> test$SalePrice <- NAn> data <- rbind(train,test) #bind_rows(train,test)會將部分變數轉換成char類型n> train.row <- 1:nrow(train)n> test.row <- (1+nrow(train)):(nrow(train)+nrow(test))n
2 數據預覽
觀察合併後的數據:
> str(data)ndata.frame:t2919 obs. of 81 variables:n $ Id : int 1 2 3 4 5 6 7 8 9 10 ...n $ MSSubClass : int 60 20 60 70 60 50 20 60 50 190 ...n $ MSZoning : Factor w/ 5 levels "C (all)","FV",..: 4 4 4 4 4 4 4 4 5 4 ...n $ LotFrontage : int 65 80 68 60 84 85 75 NA 51 50 ...n $ LotArea : int 8450 9600 11250 9550 14260 14115 10084 10382 6120 7420 ...n $ Street : Factor w/ 2 levels "Grvl","Pave": 2 2 2 2 2 2 2 2 2 2 ...n $ Alley : Factor w/ 2 levels "Grvl","Pave": NA NA NA NA NA NA NA NA NA NA ...n $ LotShape : Factor w/ 4 levels "IR1","IR2","IR3",..: 4 4 1 1 1 1 4 1 4 4 ...n $ LandContour : Factor w/ 4 levels "Bnk","HLS","Low",..: 4 4 4 4 4 4 4 4 4 4 ...n $ Utilities : Factor w/ 2 levels "AllPub","NoSeWa": 1 1 1 1 1 1 1 1 1 1 ...n $ LotConfig : Factor w/ 5 levels "Corner","CulDSac",..: 5 3 5 1 3 5 5 1 5 1 ...n $ LandSlope : Factor w/ 3 levels "Gtl","Mod","Sev": 1 1 1 1 1 1 1 1 1 1 ...n $ Neighborhood : Factor w/ 25 levels "Blmngtn","Blueste",..: 6 25 6 7 14 12 21 17 18 4 ...n $ Condition1 : Factor w/ 9 levels "Artery","Feedr",..: 3 2 3 3 3 3 3 5 1 1 ...n $ Condition2 : Factor w/ 8 levels "Artery","Feedr",..: 3 3 3 3 3 3 3 3 3 1 ...n $ BldgType : Factor w/ 5 levels "1Fam","2fmCon",..: 1 1 1 1 1 1 1 1 1 2 ...n $ HouseStyle : Factor w/ 8 levels "1.5Fin","1.5Unf",..: 6 3 6 6 6 1 3 6 1 2 ...n $ OverallQual : int 7 6 7 7 8 5 8 7 7 5 ...n $ OverallCond : int 5 8 5 5 5 5 5 6 5 6 ...n $ YearBuilt : int 2003 1976 2001 1915 2000 1993 2004 1973 1931 1939 ...n $ YearRemodAdd : int 2003 1976 2002 1970 2000 1995 2005 1973 1950 1950 ...n $ RoofStyle : Factor w/ 6 levels "Flat","Gable",..: 2 2 2 2 2 2 2 2 2 2 ...n $ RoofMatl : Factor w/ 8 levels "ClyTile","CompShg",..: 2 2 2 2 2 2 2 2 2 2 ...n $ Exterior1st : Factor w/ 15 levels "AsbShng","AsphShn",..: 13 9 13 14 13 13 13 7 4 9 ...n $ Exterior2nd : Factor w/ 16 levels "AsbShng","AsphShn",..: 14 9 14 16 14 14 14 7 16 9 ...n $ MasVnrType : Factor w/ 4 levels "BrkCmn","BrkFace",..: 2 3 2 3 2 3 4 4 3 3 ...n $ MasVnrArea : int 196 0 162 0 350 0 186 240 0 0 ...n $ ExterQual : Factor w/ 4 levels "Ex","Fa","Gd",..: 3 4 3 4 3 4 3 4 4 4 ...n $ ExterCond : Factor w/ 5 levels "Ex","Fa","Gd",..: 5 5 5 5 5 5 5 5 5 5 ...n $ Foundation : Factor w/ 6 levels "BrkTil","CBlock",..: 3 2 3 1 3 6 3 2 1 1 ...n $ BsmtQual : Factor w/ 4 levels "Ex","Fa","Gd",..: 3 3 3 4 3 3 1 3 4 4 ...n $ BsmtCond : Factor w/ 4 levels "Fa","Gd","Po",..: 4 4 4 2 4 4 4 4 4 4 ...n $ BsmtExposure : Factor w/ 4 levels "Av","Gd","Mn",..: 4 2 3 4 1 4 1 3 4 4 ...n $ BsmtFinType1 : Factor w/ 6 levels "ALQ","BLQ","GLQ",..: 3 1 3 1 3 3 3 1 6 3 ...n $ BsmtFinSF1 : int 706 978 486 216 655 732 1369 859 0 851 ...n $ BsmtFinType2 : Factor w/ 6 levels "ALQ","BLQ","GLQ",..: 6 6 6 6 6 6 6 2 6 6 ...n $ BsmtFinSF2 : int 0 0 0 0 0 0 0 32 0 0 ...n $ BsmtUnfSF : int 150 284 434 540 490 64 317 216 952 140 ...n $ TotalBsmtSF : int 856 1262 920 756 1145 796 1686 1107 952 991 ...n $ Heating : Factor w/ 6 levels "Floor","GasA",..: 2 2 2 2 2 2 2 2 2 2 ...n $ HeatingQC : Factor w/ 5 levels "Ex","Fa","Gd",..: 1 1 1 3 1 1 1 1 3 1 ...n $ CentralAir : Factor w/ 2 levels "N","Y": 2 2 2 2 2 2 2 2 2 2 ...n $ Electrical : Factor w/ 5 levels "FuseA","FuseF",..: 5 5 5 5 5 5 5 5 2 5 ...n $ X1stFlrSF : int 856 1262 920 961 1145 796 1694 1107 1022 1077 ...n $ X2ndFlrSF : int 854 0 866 756 1053 566 0 983 752 0 ...n $ LowQualFinSF : int 0 0 0 0 0 0 0 0 0 0 ...n $ GrLivArea : int 1710 1262 1786 1717 2198 1362 1694 2090 1774 1077 ...n $ BsmtFullBath : int 1 0 1 1 1 1 1 1 0 1 ...n $ BsmtHalfBath : int 0 1 0 0 0 0 0 0 0 0 ...n $ FullBath : int 2 2 2 1 2 1 2 2 2 1 ...n $ HalfBath : int 1 0 1 0 1 1 0 1 0 0 ...n $ BedroomAbvGr : int 3 3 3 3 4 1 3 3 2 2 ...n $ KitchenAbvGr : int 1 1 1 1 1 1 1 1 2 2 ...n $ KitchenQual : Factor w/ 4 levels "Ex","Fa","Gd",..: 3 4 3 3 3 4 3 4 4 4 ...n $ TotRmsAbvGrd : int 8 6 6 7 9 5 7 7 8 5 ...n $ Functional : Factor w/ 7 levels "Maj1","Maj2",..: 7 7 7 7 7 7 7 7 3 7 ...n $ Fireplaces : int 0 1 1 1 1 0 1 2 2 2 ...n $ FireplaceQu : Factor w/ 5 levels "Ex","Fa","Gd",..: NA 5 5 3 5 NA 3 5 5 5 ...n $ GarageType : Factor w/ 6 levels "2Types","Attchd",..: 2 2 2 6 2 2 2 2 6 2 ...n $ GarageYrBlt : int 2003 1976 2001 1998 2000 1993 2004 1973 1931 1939 ...n $ GarageFinish : Factor w/ 3 levels "Fin","RFn","Unf": 2 2 2 3 2 3 2 2 3 2 ...n $ GarageCars : int 2 2 2 3 3 2 2 2 2 1 ...n $ GarageArea : int 548 460 608 642 836 480 636 484 468 205 ...n $ GarageQual : Factor w/ 5 levels "Ex","Fa","Gd",..: 5 5 5 5 5 5 5 5 2 3 ...n $ GarageCond : Factor w/ 5 levels "Ex","Fa","Gd",..: 5 5 5 5 5 5 5 5 5 5 ...n $ PavedDrive : Factor w/ 3 levels "N","P","Y": 3 3 3 3 3 3 3 3 3 3 ...n $ WoodDeckSF : int 0 298 0 0 192 40 255 235 90 0 ...n $ OpenPorchSF : int 61 0 42 35 84 30 57 204 0 4 ...n $ EnclosedPorch: int 0 0 0 272 0 0 0 228 205 0 ...n $ X3SsnPorch : int 0 0 0 0 0 320 0 0 0 0 ...n $ ScreenPorch : int 0 0 0 0 0 0 0 0 0 0 ...n $ PoolArea : int 0 0 0 0 0 0 0 0 0 0 ...n $ PoolQC : Factor w/ 3 levels "Ex","Fa","Gd": NA NA NA NA NA NA NA NA NA NA ...n $ Fence : Factor w/ 4 levels "GdPrv","GdWo",..: NA NA NA NA NA 3 NA NA NA NA ...n $ MiscFeature : Factor w/ 4 levels "Gar2","Othr",..: NA NA NA NA NA 3 NA 3 NA NA ...n $ MiscVal : int 0 0 0 0 0 700 0 350 0 0 ...n $ MoSold : int 2 5 9 2 12 10 8 11 4 1 ...n $ YrSold : int 2008 2007 2008 2006 2008 2009 2007 2009 2008 2008 ...n $ SaleType : Factor w/ 9 levels "COD","Con","ConLD",..: 9 9 9 9 9 9 9 9 9 9 ...n $ SaleCondition: Factor w/ 6 levels "Abnorml","AdjLand",..: 5 5 5 1 5 5 5 5 1 5 ...n $ SalePrice : int 208500 181500 223500 140000 250000 143000 307000 200000 129900 118000 ...n
從上可知,合併後的數據集包含81個變數,2919條數據,其中1460條為訓練數據,1459條為測試數據。變數主要分為兩類,一類是int類型,一類為Factor類型,分別為38個和43個。
# 獲取數據中 factor變數的個數n> <- sapply(data, class )n> table()nvairableNumbern factor integer n 43 38 n
變數解釋如下:
- SalePrice - 房產銷售價格,以美元計價。所要預測的目標變數。
- MSSubClass: The building class 建築等級
- MSZoning: The general zoning classification 區域分類
- LotFrontage: Linear feet of street connected to property 房子同街道之間的距離
- LotArea: Lot size in square feet 建築面積
- Street: Type of road access 主路的路面類型
- Alley: Type of alley access 小道的路面類型
- LotShape: General shape of property 房屋外形
- LandContour: Flatness of the property 平整度
- Utilities: Type of utilities available 配套公用設施類型
- LotConfig: Lot configuration 配置
- LandSlope: Slope of property 土地坡度
- Neighborhood: Physical locations within Ames city limits
- Condition1: Proximity to main road or railroad 與主要公路及鐵路的距離
- Condition2: Proximity to main road or railroad (if a second is present) 與主要公路及鐵路的距離
- BldgType: Type of dwelling 住宅類型
- HouseStyle: Style of dwelling 房屋的層數
- OverallQual: Overall material and finish quality 完工質量和材料
- OverallCond: Overall condition rating 整體條件等級
- YearBuilt: Original construction date 建造年份
- YearRemodAdd: Remodel date 翻修年份
- RoofStyle: Type of roof 屋頂類型
- RoofMatl: Roof material 屋頂材料
- Exterior1st: Exterior covering on house 外立面材料
- Exterior2nd: Exterior covering on house (if more than one material) 外立面材料2
- MasVnrType: Masonry veneer type 裝飾石材類型
- MasVnrArea: Masonry veneer area in square feet 裝飾石材面積
- ExterQual: Exterior material quality 外立面材料質量
- ExterCond: Present condition of the material on the exterior 外立面材料外觀情況
- Foundation: Type of foundation 基礎類型
- BsmtQual: Height of the basement 地下室高度
- BsmtCond: General condition of the basement 地下室總體情況
- BsmtExposure: Walkout or garden level basement walls 地下室出口或者花園層的牆面
- BsmtFinType1: Quality of basement finished area 地下室區域質量
- BsmtFinSF1: Type 1 finished square feet Type 1完工面積
- BsmtFinType2: Quality of second finished area (if present) 二次完工面積質量(如果有)
- BsmtFinSF2: Type 2 finished square feet Type 2完工面積
- BsmtUnfSF: Unfinished square feet of basement area 地下室區域未完工面積
- TotalBsmtSF: Total square feet of basement area 地下室總體面積
- Heating: Type of heating 採暖類型
- HeatingQC: Heating quality and condition 採暖質量和條件
- CentralAir: Central air conditioning 中央空調系統
- Electrical: Electrical system 電力系統
- 1stFlrSF: First Floor square feet 第一層面積
- 2ndFlrSF: Second floor square feet 第二層面積
- LowQualFinSF: Low quality finished square feet (all floors) 低質量完工面積
- GrLivArea: Above grade (ground) living area square feet 地面以上部分起居面積
- BsmtFullBath: Basement full bathrooms 地下室全浴室
- BsmtHalfBath: Basement half bathrooms 地下室半浴室
- FullBath: Full bathrooms above grade 地面以上全浴室
- HalfBath: Half baths above grade 地面以上半浴室
- Bedroom: Number of bedrooms above basement level 地面以上卧室
- Kitchen: Number of kitchens 廚房數量
- KitchenQual: Kitchen quality 廚房質量
- TotRmsAbvGrd: Total rooms above grade (does not include bathrooms) 總房間數(不含浴室和地下部分)
- Functional: Home functionality rating 功能性評級
- Fireplaces: Number of fireplaces 壁爐數量
- FireplaceQu: Fireplace quality 壁爐質量
- GarageType: Garage location 車庫位置
- GarageYrBlt: Year garage was built 車庫建造時間
- GarageFinish: Interior finish of the garage 車庫中間建成時間(比如翻修)
- GarageCars: Size of garage in car capacity 車殼大小以停車數量表示
- GarageArea: Size of garage in square feet 車庫面積
- GarageQual: Garage quality 車庫質量
- GarageCond: Garage condition 車庫條件
- PavedDrive: Paved driveway 硬化路面
- WoodDeckSF: Wood deck area in square feet 實木地板面積
- OpenPorchSF: Open porch area in square feet 開放式門廊面積
- EnclosedPorch: Enclosed porch area in square feet 封閉式門廊面積
- 3SsnPorch: Three season porch area in square feet 時令門廊面積
- ScreenPorch: Screen porch area in square feet 屏幕門廊面積
- PoolArea: Pool area in square feet 游泳池面積
- PoolQC: Pool quality 游泳池質量
- Fence: Fence quality 圍欄質量
- MiscFeature: Miscellaneous feature not covered in other categories 其它條件中未包含部分的特性
- MiscVal: $Value of miscellaneous feature 雜項部分價值
- MoSold: Month Sold 賣出月份
- YrSold: Year Sold 賣出年份
- SaleType: Type of sale 出售類型
- SaleCondition: Condition of sale 出售條件
3 缺失值處理
從數據預覽的情況來看,數據集中有很多變數存在缺失值,所以在選擇合適的建模變數之前我們處理缺失值。
首先,用VIM包中的complete.cases()函數分別列出沒有缺失值和有缺失值的行,因為數據實在太多,這個方法變得價值不大。
順便插一句,因為電腦換成了Mac,在OS X EI Capitan系統下面運行的Rstudio在通過install.package()命令安裝R包時需要自行編譯,耗費時間太長,而且不知道為什麼今天我在想安裝VIM包時一開始一直在安裝依賴的時候出錯,後面只好通過去CRAN直接下載各個編譯過的二進位包通過命令行直接安裝,發現速度非常快,幾乎秒裝。命令行中的安裝包的命令如下:
R CMD INSTALL ~/Downloads/nloptr_1.0.4.tgzn
INSTALL 後面是包的路徑,相對路徑還是絕對路徑取決於當前的所在目錄~
下面用matrixplot()函數繪製缺失值情況。
> matrixplot(data)n
數值型數據被轉換到[0,1]區間,並用灰度來表示大小,缺失值默認用紅色表示。
大致地可以看出有部分數據缺失非常嚴重,比如Alley,Fence等。下面用定量的方法獲得各個變數的缺失情況並進行排序。
# 統計所有變數的缺失值ntemp <- sapply(data, function(x) sum(is.na(x)) )nn# 按照缺失率排序nmiss <- sort(temp, decreasing=T)nmiss[miss>0]n
執行結果如下:這裡只給出了有缺失值的變數,並進行了人工注釋。
# 變數 缺失數 缺失比例 含義nPoolQC 2909 100% # 泳池質量nMiscFeature 2814 96% # 特殊的設施nAlley 2721 93% # 房屋附近的小巷nFence 2348 80% # 房屋的籬笆nFireplaceQu 1420 49% # 壁爐的質量nnLotFrontage 486 17% # 房子同街道之間的距離nnGarageYrBlt 159 5% # 車庫nGarageFinish 159 5%nGarageQual 159 5%nGarageCond 159 5%nGarageType 157 5%nnBsmtCond 82 3% # 地下室nBsmtExposure 82 3%nBsmtQual 81 3%nBsmtFinType2 80 3%nBsmtFinType1 79 3%nnMasVnrType 24 1% # 外牆裝飾石材類型nMasVnrArea 23 1% # 外牆裝飾石材面積nnMSZoning 4 0% # 其他nUtilities 2 0%nBsmtFullBath 2 0%nBsmtHalfBath 2 0%nFunctional 2 0%nExterior1st 1 0%nExterior2nd 1 0%nBsmtFinSF1 1 0%nBsmtFinSF2 1 0%nBsmtUnfSF 1 0%nTotalBsmtSF 1 0%nElectrical 1 0%nKitchenQual 1 0%nGarageCars 1 0%nGarageArea 1 0%nSaleType 1 0%n
然後查看有缺失值的變數的概括。
> summary(data[,names(miss)[miss>0]])n PoolQC MiscFeature Alley Fence SalePrice FireplaceQu n Length:2919 Length:2919 Length:2919 Length:2919 Min. : 34900 Length:2919 n Class :character Class :character Class :character Class :character 1st Qu.:129975 Class :character n Mode :character Mode :character Mode :character Mode :character Median :163000 Mode :character n Mean :180921 n 3rd Qu.:214000 n Max. :755000 n NAs :1459 n LotFrontage GarageYrBlt GarageFinish GarageQual GarageCond GarageType n Min. : 21.00 Min. :1895 Length:2919 Length:2919 Length:2919 Length:2919 n 1st Qu.: 59.00 1st Qu.:1960 Class :character Class :character Class :character Class :character n Median : 68.00 Median :1979 Mode :character Mode :character Mode :character Mode :character n Mean : 69.31 Mean :1978 n 3rd Qu.: 80.00 3rd Qu.:2002 n Max. :313.00 Max. :2207 n NAs :486 NAs :159 n BsmtCond BsmtExposure BsmtQual BsmtFinType2 BsmtFinType1 MasVnrType n Length:2919 Length:2919 Length:2919 Length:2919 Length:2919 Length:2919 n Class :character Class :character Class :character Class :character Class :character Class :character n Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character n n n n n MasVnrArea MSZoning Utilities BsmtFullBath BsmtHalfBath Functional n Min. : 0.0 Length:2919 Length:2919 Min. :0.0000 Min. :0.00000 Length:2919 n 1st Qu.: 0.0 Class :character Class :character 1st Qu.:0.0000 1st Qu.:0.00000 Class :character n Median : 0.0 Mode :character Mode :character Median :0.0000 Median :0.00000 Mode :character n Mean : 102.2 Mean :0.4299 Mean :0.06136 n 3rd Qu.: 164.0 3rd Qu.:1.0000 3rd Qu.:0.00000 n Max. :1600.0 Max. :3.0000 Max. :2.00000 n NAs :23 NAs :2 NAs :2 n Exterior1st Exterior2nd BsmtFinSF1 BsmtFinSF2 BsmtUnfSF TotalBsmtSF n Length:2919 Length:2919 Min. : 0.0 Min. : 0.00 Min. : 0.0 Min. : 0.0 n Class :character Class :character 1st Qu.: 0.0 1st Qu.: 0.00 1st Qu.: 220.0 1st Qu.: 793.0 n Mode :character Mode :character Median : 368.5 Median : 0.00 Median : 467.0 Median : 989.5 n Mean : 441.4 Mean : 49.58 Mean : 560.8 Mean :1051.8 n 3rd Qu.: 733.0 3rd Qu.: 0.00 3rd Qu.: 805.5 3rd Qu.:1302.0 n Max. :5644.0 Max. :1526.00 Max. :2336.0 Max. :6110.0 n NAs :1 NAs :1 NAs :1 NAs :1 n Electrical KitchenQual GarageCars GarageArea SaleType n Length:2919 Length:2919 Min. :0.000 Min. : 0.0 Length:2919 n Class :character Class :character 1st Qu.:1.000 1st Qu.: 320.0 Class :character n Mode :character Mode :character Median :2.000 Median : 480.0 Mode :character n Mean :1.767 Mean : 472.9 n 3rd Qu.:2.000 3rd Qu.: 576.0 n Max. :5.000 Max. :1488.0 n NAs :1 NAs :1 n> n
下面對缺失值進行處理。
缺失值的處理無非這麼兩種,要麼刪除,要麼找合理的值進行替代,具體可以看下面這篇文章的介紹:
《R語言實戰》第四部分第十八章-處理缺失數據的高級方法學習筆記
下面從簡單的做起,對於缺失量比較多的PoolQC、MiscFeature、Alley、Fence、FireplaceQu是由於房子本身並沒有這些設施。因此,我們可以直接刪除這幾個變數。
> Drop <- names(data) %in% c("PoolQC","MiscFeature","Alley","Fence","FireplaceQu")n> data <- data[!Drop]n
接下來車庫相關的五個變數GarageType、GarageYrBlt、GarageFinish、GarageQual、GarageCond也是由於房子沒有車庫而缺失。
同樣,BsmtExposure、BsmtFinType2、BsmtQual、BsmtCond、BsmtFinType1五個變數是與地下室相關的,都是由於房子沒有地下室而缺失。
對於這樣的數據,缺失的數量比較少,可以直接用None 來代替缺失值。將變數因子化,並將None視作一個新的因子。
# 將如下變數的NA值填充為NonenGarage <- c("GarageType","GarageQual","GarageCond","GarageFinish")nBsmt <- c("BsmtExposure","BsmtFinType2","BsmtQual","BsmtCond","BsmtFinType1")nfor (x in c(Garage, Bsmt) )n{ndata[[x]] <- factor( data[[x]], levels= c(levels(data[[x]]),c(None)))ndata[[x]][is.na(data[[x]])] <- "None"n}n
與車庫相關的還有一個GarageYrBlt,即車庫建造的年份,假設車庫與房子同時完工,我們用房子的建造年份(YearBuilt)來代替。
> data$GarageYrBlt[is.na(data$GarageYrBlt)] <- data$YearBuilt[is.na(data$GarageYrBlt)]n
下面再逐個處理有缺失值的變數。
有17%缺失率的LotFrontage 房子同街道之間的距離,這是一個數值變數,我們用平均值來補充。
#用平均值來填充缺失值n> data$LotFrontage[is.na(data$LotFrontage)] <- mean(data$LotFrontage, na.rm = T)n
查看變數MasVnrType 外牆裝飾石材類型,發現缺失數據比例不大,且本身None最多,即為這一變數的眾數。因此,MasVnrType中的NA用它本身的None來代替。
#用MasVnrType變數中的眾數None 填充缺失值n> data[["MasVnrType"]][is.na(data[["MasVnrType"]])] <- "None"n
變數MasVnrArea是外牆裝飾石材的面積,這個變數與MasVnrType是相關聯的,與None取值對應的應該直接為0。
#用0補充無外牆的面積n> data[["MasVnrArea"]][is.na(data[["MasVnrArea"]])] <- 0n
變數Utilities 大部分都是AllPub,可以說公共配套設施都比較齊全,這樣導致這個變數區分度不大,對於預測沒有作用,直接丟棄。
#刪除Utilities變數n> data$Utilities <- NULLn
變數 BsmtFullBath BsmtHalfBath BsmtFinSF1 BsmtFinSF2 BsmtUnfSF TotalBsmtSF 都是與地下室相關,這些變數的數據缺失都是沒有地下室相關的設施造成的,並且這些變數都是數值型變數,而且缺失比例很少,建議直接用0來填充即可。這與前面對與設施相關的字元型變數用「None」填充的處理方法類似。
#由於地下室相關設施缺失導致數據缺失,用0填充n> Bsm0 <- c("BsmtFullBath","BsmtHalfBath","BsmtFinSF1","BsmtFinSF2","BsmtUnfSF","TotalBsmtSF")n> for (x in Bsm0 ) data[[x]][is.na(data[[x]])] <- 0n
同理變數 GarageCars GarageArea 則是由於不存在車庫造成的,且只缺失一個數據,亦可用0填充。
> Gara0 <- c("GarageCars","GarageArea")n> for (x in Gara0 ) data[[x]][is.na(data[[x]])] <- 0n
剩下的變數都是字元型變數,並且只有個位數的缺失值,可以像數值型變數用眾數代替的理念用各自出現最多的字元來代替。
> Req <- c("MSZoning","Functional","Exterior1st","Exterior2nd","KitchenQual","Electrical","SaleType")n> for (x in Req) {n data[[x]][is.na(data[[x]])] <- levels(data[[x]])[which.max(table(data[[x]]))]n}n
經過一系列的缺失值補齊之後,最後剩下75個變數,並且數據都已經補充完整。
為了便於後續模型訓練做準備,我們先講處理後的數據集拆分為訓練集和測試集。
train <- data[train.row,]ntest <- data[test.row,]n
4 回歸模型
對著房價的預測,可以採用很多模型,比如線性回歸、隨即森林、梯度下降決策樹等。我們從最簡單的線性回歸開始。
因為變數比較多,本來想到先做一下主成分分析,不過考慮到大部分為因子型或者字元型變數,暫時還不適用於主成分分析,有興趣的讀者可以自行試試。
自變數如何選擇是線性回歸的最主要的一步工作,選擇那些與預測的響應變數相關度比較高的特徵變數是模型成功的基礎,而變數選擇最基礎的方法就是分析師根據業務場景和邏輯進行人工篩選。
房價預測也是當下比較熱門的話題,我們不妨以目前國內的房價為例,影響房價的因素主要是房子面積、房子所在的區域、小區等,房齡、房型(小高層、多層、別墅等)、特殊場景(地鐵房、學區房等)、交易時間、外立面材料及裝修等也會影響價格。
這個數據是美國的房屋信息,不過基本的影響因素應該也差不多。
我們先來簡單的整出一個模型來,選擇如下變數:
- LotArea :房子的面積
- Neighborhood :城市街區 用來初步代替 區域、小區
- Condition1 Condition2: 附近的交通情況
- BldgType :房屋類型 獨棟別墅、聯排別墅
- HouseStyle :房子的層數
- YearBuilt :房子建造的年份
- YearRemodAdd: 房子的改造年份
- OverallQual:房子整體質量,考量材料和完成度
- MoSold: 賣出月份
- YrSold: 賣出年份
- ExterQual: 外立面材料質量
- ExterCond: 外立面材料外觀情況
先用我們挑選出來的變數建立一個lm模型,作為後面與其它模型對比的基本模型。
#通過人工選擇的變數構造擬合公式n> fm.base <- SalePrice ~ LotArea + Neighborhood + Condition1 + Condition2 + BldgType + HouseStyle + YearBuilt + YearRemodAdd + MoSold + YrSold + ExterQual + ExterCondn#訓練模型n> lm.base <- lm(fm.base, train)n#查看模型概要n> summary(lm.base)n
模型概要結果如下:
Call:nlm(formula = fm.base, data = train)nnResiduals:n Min 1Q Median 3Q Max n-211695 -20833 -2811 16133 408732 nnCoefficients:n Estimate Std. Error t value Pr(>|t|) n(Intercept) 1.789e+06 1.732e+06 1.033 0.301620 nLotArea 1.183e+00 1.254e-01 9.437 < 2e-16 ***nNeighborhoodBlueste -5.662e+03 3.210e+04 -0.176 0.860038 nNeighborhoodBrDale -2.550e+04 1.665e+04 -1.532 0.125780 nNeighborhoodBrkSide -4.056e+04 1.399e+04 -2.899 0.003805 ** nNeighborhoodClearCr -1.818e+04 1.442e+04 -1.261 0.207508 nNeighborhoodCollgCr -4.337e+04 1.173e+04 -3.698 0.000225 ***nNeighborhoodCrawfor 1.332e+04 1.353e+04 0.984 0.325178 nNeighborhoodEdwards -5.647e+04 1.263e+04 -4.473 8.34e-06 ***nNeighborhoodGilbert -5.989e+04 1.253e+04 -4.779 1.94e-06 ***nNeighborhoodIDOTRR -5.883e+04 1.466e+04 -4.013 6.32e-05 ***nNeighborhoodMeadowV -2.875e+04 1.567e+04 -1.834 0.066837 . nNeighborhoodMitchel -4.587e+04 1.305e+04 -3.515 0.000454 ***nNeighborhoodNAmes -4.067e+04 1.227e+04 -3.314 0.000945 ***nNeighborhoodNoRidge 6.623e+04 1.326e+04 4.994 6.65e-07 ***nNeighborhoodNPkVill 9.669e+03 1.808e+04 0.535 0.592970 nNeighborhoodNridgHt 3.907e+04 1.211e+04 3.226 0.001285 ** nNeighborhoodNWAmes -2.649e+04 1.283e+04 -2.066 0.039059 * nNeighborhoodOldTown -4.452e+04 1.354e+04 -3.287 0.001038 ** nNeighborhoodSawyer -4.966e+04 1.295e+04 -3.834 0.000132 ***nNeighborhoodSawyerW -3.189e+04 1.255e+04 -2.540 0.011187 * nNeighborhoodSomerst -2.041e+04 1.183e+04 -1.725 0.084787 . nNeighborhoodStoneBr 6.995e+04 1.352e+04 5.175 2.62e-07 ***nNeighborhoodSWISU -3.786e+04 1.557e+04 -2.431 0.015162 * nNeighborhoodTimber -1.541e+04 1.338e+04 -1.151 0.249880 nNeighborhoodVeenker 1.994e+04 1.683e+04 1.185 0.236331 nCondition1Feedr -9.521e+03 8.327e+03 -1.143 0.253068 nCondition1Norm -1.445e+03 6.916e+03 -0.209 0.834491 nCondition1PosA 3.523e+04 1.667e+04 2.114 0.034727 * nCondition1PosN 2.888e+04 1.252e+04 2.307 0.021204 * nCondition1RRAe -2.803e+04 1.496e+04 -1.873 0.061307 . nCondition1RRAn -7.190e+02 1.153e+04 -0.062 0.950282 nCondition1RRNe -3.789e+04 3.112e+04 -1.218 0.223501 nCondition1RRNn 1.147e+04 2.080e+04 0.551 0.581526 nCondition2Feedr 1.011e+03 3.752e+04 0.027 0.978506 nCondition2Norm 4.672e+02 3.220e+04 0.015 0.988424 nCondition2PosA 5.947e+04 6.262e+04 0.950 0.342402 nCondition2PosN -1.176e+05 4.563e+04 -2.578 0.010028 * nCondition2RRAe 3.780e+04 5.403e+04 0.700 0.484272 nCondition2RRAn -1.417e+04 5.372e+04 -0.264 0.792043 nCondition2RRNn -1.934e+04 4.419e+04 -0.438 0.661650 nBldgType2fmCon -5.485e+03 8.561e+03 -0.641 0.521853 nBldgTypeDuplex -9.580e+03 6.444e+03 -1.487 0.137323 nBldgTypeTwnhs -7.253e+04 8.478e+03 -8.555 < 2e-16 ***nBldgTypeTwnhsE -5.487e+04 5.306e+03 -10.340 < 2e-16 ***nHouseStyle1.5Unf -2.131e+04 1.217e+04 -1.752 0.080066 . nHouseStyle1Story -1.516e+04 4.400e+03 -3.445 0.000588 ***nHouseStyle2.5Fin 7.840e+04 1.600e+04 4.900 1.07e-06 ***nHouseStyle2.5Unf 1.467e+04 1.415e+04 1.037 0.299903 nHouseStyle2Story 3.937e+03 4.644e+03 0.848 0.396774 nHouseStyleSFoyer -1.937e+04 8.526e+03 -2.271 0.023271 * nHouseStyleSLvl -6.324e+03 6.790e+03 -0.931 0.351853 nYearBuilt 6.380e+02 8.891e+01 7.176 1.16e-12 ***nYearRemodAdd 4.649e+02 7.649e+01 6.078 1.57e-09 ***nMoSold -3.552e+02 4.196e+02 -0.846 0.397453 nYrSold -1.815e+03 8.570e+02 -2.118 0.034334 * nExterQualFa -1.461e+05 1.460e+04 -10.013 < 2e-16 ***nExterQualGd -9.554e+04 6.965e+03 -13.717 < 2e-16 ***nExterQualTA -1.242e+05 7.620e+03 -16.300 < 2e-16 ***nExterCondFa -1.111e+04 3.129e+04 -0.355 0.722522 nExterCondGd 3.212e+03 3.015e+04 0.107 0.915189 nExterCondPo -3.958e+04 5.203e+04 -0.761 0.446978 nExterCondTA -9.390e+02 3.003e+04 -0.031 0.975057 n---nSignif. codes: 0 『***』 0.001 『**』 0.01 『*』 0.05 『.』 0.1 『 』 1nnResidual standard error: 42010 on 1397 degrees of freedomnMultiple R-squared: 0.7323,tAdjusted R-squared: 0.7204 nF-statistic: 61.63 on 62 and 1397 DF, p-value: < 2.2e-16n
針對模型summary之後的結果,進行簡單的解讀。
殘差統計量
Residuals:n Min 1Q Median 3Q Max n-211695 -20833 -2811 16133 408732 n
線性回歸的計算基於一些假設,其中一個假設就是 誤差符合相互獨立、均值為 0 的正態分布。
從本例可以看出這個殘差的中位數為負數,數據整體左偏。其中的 1Q 和 3Q 是第一四分位(first quartile)和第三四分位(third quartile)。殘差的最大值和最小值附近對應的記錄則可能是異常值。
由於殘差代表預測值和真實值之間的差別,也就是說最大值 408732表示我們預測的最大誤差有 40 萬美元之多。最小值相差也在21萬美元左右。
回歸係數
Coefficients:n Estimate Std. Error t value Pr(>|t|) n(Intercept) 1.789e+06 1.732e+06 1.033 0.301620 nLotArea 1.183e+00 1.254e-01 9.437 < 2e-16 ***nNeighborhoodBlueste -5.662e+03 3.210e+04 -0.176 0.860038 nNeighborhoodBrDale -2.550e+04 1.665e+04 -1.532 0.125780 nNeighborhoodBrkSide -4.056e+04 1.399e+04 -2.899 0.003805 ** n...n...n---nSignif. codes: 0 『***』 0.001 『**』 0.01 『*』 0.05 『.』 0.1 『 』 1n
線性回歸擬合完成後得出的回歸係數並不是準確的值,而是對於真實回歸係數的估計值。
既然是估計值則必然存在誤差,上述結果中的:
- Estimate 表示回歸係數的估計
- Std. Error 表示回歸係數的標準誤差
- t value 表示假設此回歸係數為 0 時的 T 檢驗值- Pr(>|t|) 則是上述假設成立的置信度 p-valueP-value 越小則說明假設(假設回歸係數為 0)越不容易出現,反過來就是此變數的回歸係數不為 0 的幾率越大,故此變數在整個回歸擬合中作用越顯著。一般用置信度 0.05 作為判斷依據。
- 最後的三顆星表示此變數顯著,星號越多越顯著,最多三個。
- 最後一行 Signif. codes 標識著顯著標識編碼當 P-value 小於 0.001 時三顆星,小於 0.01 時兩顆星,大於 0.05 則認為不太顯著。
根據以上原則,本例MoSold 和ExterCond這兩個變數不太顯著,後續可以考慮去除。
R 方和調整後的R方
Multiple R-squared: 0.7323,tAdjusted R-squared: 0.7204 n
R-squared(判定係數,coefficient of determination)
也稱為模型擬合的確定係數,取值 0~1 之間,越接近 1,表明模型的因變數對響應變數 y 的解釋能力越強。Adjusted R-squared當自變數個數增加時,儘管有的自變數與 y 的線性關係不顯著,R square 也會增大。Adjusted R square 增加了對變數增多的懲罰,故我們以 Adjusted R square 為判斷模型好壞的基本標準。
本例中 Adjusted R-squared: 0.7204 表示響應變數有 72%的方差被此模型解釋了。
模型整體的F檢驗
F-statistic: 61.63 on 62 and 1397 DF, p-value: < 2.2e-16n
F 統計量用來檢驗模型是否顯著
假設模型所有的回歸係數均為 0,即該模型是不顯著的。對此假設做 F 檢驗,在 p-value 的置信度下拒絕了此假設,則模型為顯著的。
在本例中 p-value: < 2.2e-16,遠遠低於 0.05,所以模型是顯著的。
從這個模型的結果可以看到MoSold 變數和 ExterCond變數並不顯著,所以我們減少兩個變數繼續擬合。
擬合結果 Adjusted R-squared: 0.7206 和之前相差不大, 並且所有的變數都顯著。
故我們將第一個模型定為:
#初步決定的lm.base 模型的變數n> fm.base <- SalePrice ~ LotArea + Neighborhood + Condition1 + Condition2 + BldgType + HouseStyle + YearBuilt + YearRemodAdd + YrSold + ExterQualn#訓練模型n> lm.base <- lm(fm.base, train)n
接下來用base模型計算答案提交一次,看看結果如何。
#用lm.base模型預測n> lm.pred <- predict(lm.base, test)n#寫出結果文件n> temp <- data.frame(Id = test$Id, SalePrice = lm.pred)n> write.csv(temp, file = "price_base.csv", row.names = FALSE)n
Your submission scored 0.22357, which is not an improvement of your best score. Keep trying!
排名1700名開外,結果有點慘。
5 模型優化
複習一下這篇文章 《R語言實戰》第三部分第八章-回歸複習筆記 ,我們知道對於線性回歸,是需要滿足一些假設的。我們不妨通過plot給出模型的線性回歸診斷圖。
# 快速列印殘差圖、QQ 圖等n> layout(matrix(1:4,2,2))n> plot(lm.base)n
- 殘差-擬合圖(Residuals vs Fitted)
線性回歸的計算基於一些假設,其中假設誤差是相互獨立、均值為 0 正態分布。如果因變數與自變數線性相關的,那麼殘差的分布應該是正態分布。 通過上圖可以看出,殘差整體是隨機分布在均線 0 值附近的。殘差比較大的點很大幾率是異常點,需要去除掉。
- 尺度-位置圖(Scale-Location Graph)
因變數的方差不隨自變數的水平不同而變化,稱為同方差性(殘差方差不變)。 如果殘差滿足不變方差假設,那麼在尺度-位置圖中,水平線周圍的點應該隨機分布,那麼紅線應該是比較直的一條線。
- 正態 Q-Q 圖(Normal Q-Q)
正態 Q-Q 圖是在正態分布對應的值下標準化殘差的概率圖。如果殘差滿足相互獨立、均值為 0 正態分布的假設,那麼圖上的點應該落在呈 45 度角的直線上。通過圖上可以看到異常值的殘差偏離 45 度線比較多。
- 殘差與槓桿圖(Residuals vs Leverage)
這個圖形主要用來鑒別出離群點、高槓桿值點和強影響點。擬合比較好的模型中所有的點都不應該超過 0.5 倍 Cook 距離,也即是不超過圖中 0.5 的那根紅色點線。
我們通過診斷圖看到整體的模型裡面有很多的離群點或者異常值,這些異常值會影響模型的整體擬合質量。所以我們下一步則通過 Cook 距離來去除掉所有的異常點。
一般對於 4 倍以上的 Cook 平均距離的點作為異常點的監測標準。
> # 通過 cook 距離來查看異常點n> cooksd <- cooks.distance(lm.base)n> n> # 畫圖n> plot(cooksd, pch=".", cex=1, main="不同cook距離的影響") # 繪製cook距離n> abline(h = 4*mean(cooksd, na.rm=T), col="red") # 添加截止分界線n> text(x=1:length(cooksd)+1, y=cooksd, labels=ifelse(cooksd>20*mean(cooksd, na.rm=T),names(cooksd),""), col="blue") # 添加圖簽n> n
在訓練集中將異常點去除
# 4倍以上的為異常點n> influential <- as.numeric(names(cooksd)[(cooksd > 4*mean(cooksd, na.rm=T))])n#上一條中得到的influential有NA值需要去除n> influential <- influential[!is.na(influential)]n#去除訓練數據中的異常值n> train <- train[ -influential, ]n
同時,為了使得數字變數的分布更趨向於正態化,分別對數值型變數取對數,包括響應變數。在模型訓練完成對測試數據進行預測後在反對數計算回去。
新的公式如下:
#初步決定的lm.base 模型的變數n> fm.base <- log(SalePrice) ~ log(LotArea) + Neighborhood + Condition1 + Condition2 + BldgType + HouseStyle + YearBuilt + YearRemodAdd + YrSold + ExterQualn#訓練模型n> lm.base <- lm(fm.base, train)n
重新訓練後,得到新的的 Adjusted R-squared: 0.7725,相比之前的有所提高。
這裡將測試數據代入新模型時碰到了以下兩個問題:
#試圖用新模型計算預測值失敗n> lm.pred <- predict(lm.base,test)nError in model.frame.default(Terms, newdata, na.action = na.action, xlev = object$xlevels) : n 因子Neighborhood里出現了新的層次Bluesten> lm.pred <- predict(lm.base,test)nError in model.frame.default(Terms, newdata, na.action = na.action, xlev = object$xlevels) : n 因子Condition2里出現了新的層次Artery, PosNn
從提示來看就是測試數據當中有模型當中並沒有的因子,原因在於前面刪除異常值的時候將一些train當中的一些與test共有的一些因子,比如Neighborhood 變數當中的 Blueste因子,以及Condition2 變數當中的Artery和PosN因子,一起都刪除了,導致新的模型裡面根本沒有這些因子的信息。於是現在用含有這幾個因子的test數據集來預測SalePrice的時候報錯。這裡的處理也比較簡單,看了一下在test數據集當中這幾個因子出現的次數也非常少,就按缺失值的處理方法來處理,分布用該變數當中出現最多的因子來代替,處理代碼如下:
# Neighborhood變數處理,一個for循環,一個條件判斷nfor(i in 1:length(test[["Neighborhood"]])){n if (test[["Neighborhood"]][i] == "Blueste"){n test[["Neighborhood"]][i] <- levels(data[["Neighborhood"]])[which.max(table(test[["Neighborhood"]]))]n }n n}nn#Condition2變數處理,一個for循環,一個條件判斷nfor(i in 1:length(test[["Condition2"]])){n if (test[["Condition2"]][i] == "Artery" | test[["Condition2"]][i] == "PosN"){n test[["Condition2"]][i] <- levels(data[["Condition2"]])[which.max(table(test[["Condition2"]]))]n }n n}n
處理以後對test進行預測:
> lm.pred <- predict(lm.base,test)n> res <- data.frame(Id = test$Id, SalePrice = exp(lm.pred))n> write.csv(res, file = "price_base_log.csv", row.names = FALSE)n
結果如下:
You advanced 21 places on the leaderboard!
Your submission scored 0.21612, which is an improvement of your previous score of 0.22357. Great job!
結果有所提高,但是不夠明顯。
6 逐步回歸
回歸分析最重要的是在於變數的選擇。前面我們只是根據自己的理解來人工選擇自變數,結果也一般,下面將根據已有的一些演算法,比如逐步回歸,根據一定的策略進行自動的選擇。
逐步回歸中,模型會一次添加或者刪除一個變數,直到達到某個判停準則為止。
向前逐步回歸(forward stepwise)每次添加一個預測變數到模型中,直到添加變數不會使模型有所改進為止。
向後逐步回歸(backward stepwise)從模型包含所有預測變數開始,一次刪除一個變數直到會降低模型質量為止。
我們這裡選擇向前逐步回歸。
首先定義取空函數和全函數:
# 取空函數和全函數nempty=lm(log(SalePrice)~1, data=train)nfull=lm(log(SalePrice)~ .-Id , data=train) n
用step()函數進行逐步回歸:
#設置隨機數nset.seed(1234)n#逐步回歸,向前計算nlm.for <- step(null, scope=list(lower=null, upper=full), direction="forward")n#查看擬合結果nsummary(lm.for)n#得到的擬合模型如下nCall:nlm(formula = log(SalePrice) ~ OverallQual + GrLivArea + Neighborhood + n BsmtFinSF1 + OverallCond + YearBuilt + TotalBsmtSF + GarageArea + n MSZoning + BldgType + SaleCondition + Functional + LotArea + n KitchenQual + CentralAir + Condition1 + BsmtExposure + Heating + n Fireplaces + BsmtFullBath + HeatingQC + ScreenPorch + WoodDeckSF + n GarageCars + SaleType + Exterior1st + YearRemodAdd + GarageQual + n ExterCond + LotFrontage + Foundation + OpenPorchSF + LotConfig + n EnclosedPorch + KitchenAbvGr + GarageCond + Street + PavedDrive + n LandSlope + HalfBath + FullBath + PoolArea, data = train)n
調整R方為0.9328,結果有一些進步。
將逐步回歸的模型用於預測並再提交一下:
> lm.pred <- predict(lm.for,test)nWarning message:nIn predict.lm(lm.for, test) : 用秩缺乏擬合來進行預測的結果很可能不可靠n> res <- data.frame(Id = test$Id, SalePrice = exp(lm.pred))n> write.csv(res, file = "price_step.csv", row.names = FALSE)n> n
Your Best Entry
You advanced 976 places on the leaderboard!Your submission scored 0.12603, which is an improvement of your previous score of 0.21612. Great job!
非常棒,結果越來越好!
7 LASSO回歸
細心的讀者不難發現,在上面用逐步回歸得到的模型用於預測test數據集時有一條warning message:In predict.lm(lm.for, test) : 用秩缺乏擬合來進行預測的結果很可能不可靠
確實,一般的線性回歸使用最小二乘 OLS 進行回歸計算很容易造成過擬合,雜訊得到了過分的關注,訓練數據的微小差異可能帶來巨大的模型差異。
而LASSO回歸的特點是採用L1正則的方法進行特徵的選擇,在擬合廣義線性模型的同時進行變數篩選(Variable Selection)和複雜度調整(Regularization)。這裡的變數篩選是指不把所有的變數都放入模型中進行擬合,而是有選擇的把變數放入模型從而得到更好的性能參數。 複雜度調整是指通過一系列參數控制模型的複雜度,從而避免過度擬合(Overfitting)。 對於線性模型來說,複雜度與模型的變數數有直接關係,變數數越多,模型複雜度就越高。 更多的變數在擬合時往往可以給出一個看似更好的模型,但是同時也面臨過度擬合的危險。 此時如果用全新的數據去驗證模型(Validation),通常效果很差。 一般來說,變數數大於數據點數量很多,或者某一個離散變數有太多獨特值時,都有可能過度擬合。
在R中可以用LASSO回歸的發明人,斯坦福統計學家Trevor Hastie開發的glmnet包進行LASSO回歸。
# 安裝ninstall.packages("glmnet")nlibrary(glmnet)nn# 準備數據nLASSO_formula <- as.formula( log(SalePrice)~ .-Id )nn# model.matrix 會自動將分類變數變成啞變數nx <- model.matrix(LASSO_formula, train)ny <- log(train$SalePrice)nn#執行 lasso nset.seed(1234)nlm.lasso <- cv.glmnet(x, y, alpha=1)nn#由於 SalePrice 為 NA 無法數組化ntest$SalePrice <- 1ntest_x <- model.matrix(formula, test)nn# 預測、輸出結果nlm.pred <- predict(lm.lasso, newx = test_x, s = "lambda.min")nres <- data.frame(Id = test$Id, SalePrice = exp(lm.pred))nwrite.csv(res, file = "price_lasso.csv", row.names = FALSE)n#在上傳之前需要手動將price_lasso.csv文件的變數名改成SalePricen
再次上傳,結果如下:
Your Best Entry
You advanced 179 places on the leaderboard!Your submission scored 0.12207, which is an improvement of your previous score of 0.12603. Great job!
8 其它方法
8.1 隨機森林
隨機森林能夠處理很高維度的數據,並且不用做特徵選擇,會自動的選取變數,所以直接將所有變數都放進去。
#設置隨機數為1234n> set.seed(1234)n#建立模型n> model <- cforest(log(SalePrice)~.-Id, data = train, controls=cforest_unbiased(ntree=2000, mtry=3))n#預測數據並輸出結果n> predict.result <- predict(model,test,OOB=TRUE,type="response")n> res <- data.frame(Id = test$Id, SalePrice = exp(predict.result))n> write.csv(res, file = "price_rf.csv", row.names = FALSE)n
Your submission scored 0.20170, which is not an improvement of your best score. Keep trying!
隨機森林的結果不如LASSO回歸。
8.2 梯度下降GBDT
GBDT 全稱為 Gradient Boosting Decision Tree,它是一種基於決策樹(decision tree) 實現的分類回歸演算法。它和隨機森林一樣都是模型組合的一種,都是將簡單的模型組合起來,效果比單個更複雜的模型好。
組合的方式不同導致演算法不同,隨機森林用了隨機化方法,而 GBDT 則使用了 Gradient Boosting 的方法。
# 安裝包ninstall.packages("gbm")ninstall.packages("caret")nn#導入包nlibrary(gbm)nlibrary(caret)nn#設定種子nset.seed(1234)nn# 設定控制參數n# method = "cv" -- k 折交叉驗證 n# number -- K 折交叉驗證中的 K, number=10 則是 10 折交叉驗證n# repeats -- 交叉驗證的次數n# verboseIter -- 列印訓練日誌nctrl <- trainControl(method = "cv", number = 10, repeats = 20, verboseIter = TRUE)nn# 訓練模型nlm.gbm <- train(log(SalePrice)~ .-Id, data = train, method = "gbm", trControl = ctrl)nn# 輸出結果 nlm.pred <- predict(lm.gbm, test)nres <- data.frame(Id = test$Id, SalePrice = exp(lm.pred))nwrite.csv(res, file = "price_gbm.csv", row.names = FALSE)n
Your submission scored 0.12985, which is not an improvement of your best score. Keep trying!
GBDT的結果也不如LASSO回歸。
9 結果匯總
我們上面分別使用了不同的演算法來進行訓練、預測,提交答案的最後結果如下:
- 異常值處理之前的線性回歸:0.22357
- 異常值處理之後的線性回歸:0.21612
- 逐步回歸: 0.12603
- LASSO回歸: 0.12207
- 隨機森林: 0.20170
- 梯度下降GBDT: 0.12985
10 小結
本次主要對Kaggle上面的house prices的數據進行了處理,包括特徵變數的處理、缺失值的補齊、異常值的去除,並以線性回歸模型進行了訓練和預測。反過來從線性模型的假設條件出發對原數據的一些異常值進行了處理,進一步提高的模型的精度。
後面還採用了逐步回歸、LASSO回歸進一步提高的模型的精讀。
除了回歸模型,還嘗試了隨機森林和梯度下降,結果也沒有太大的提高。後續想要進一步提供成績,還需要在特徵變數處理上下功夫。
參考文章
- R in Action, Second Edition . Robert I. Kabacoff
- 熱門數據挖掘模型應用入門(一): LASSO回歸
- Kaggle實戰:House Prices: Advanced Regression Techniques(上篇)
- Kaggle實戰:House Prices: Advanced Regression Techniques(2)
推薦閱讀:
※《Machine Learning:Regression》課程1-3章問題集
※回歸演算法之線性回歸
※線性回歸中的 ANOVA 的作用是什麼?
※求一條直線使得這條直線到給定點集距離的平方和最小。應該怎麼推導?