kaggle房价预测特征意思_R语言实战:复杂数据处理和分析之Kaggle房价预测
1)明確分析的目的
本次數據分析的數據來源于kaggle上有關于房價預測,數據來源:House Prices: Advanced Regression Techniques。此次的分析目的已經很明確了,即根據已有數據對房屋的價格進行分析,從而預測價格走勢。
2)數據收集
上文已經提到本文的分析數據來源。那么本部分就只需將已取得的數據讀取到R中,做數據處理前的準備,這里就用到此前學習過的R讀取excel的方式,這里我們稍微復習一下:
(1)使用R自帶函數:read.csv();
(2)借助于“包”:有xlsx、XLConnect或openxlsx。
這里我們采用直接采用函數read.csv,從R數據統計結果中可以看到,本數據一共包含81個變量,共1460組數據。
> HPdata<-read.csv("C:/Users/PYD/Desktop/train.csv")可以看到數據已讀取到R中3)數據處理
數據處理這一部分主要就是對已取得的數據進行整理,以方便我們后續進行分析。主要包含有缺失值處理、數據格式處理、更改錯誤信息、增加新變量等。
(1)缺失值處理
數據分析之前,要先進行缺失值處理,看一下缺失值具體出現在哪些特征里,缺失信息對整個特征是否有重要的影響。首先我們先進行缺失情況的統計。
a)識別缺失數據
因本文數據所含特征值比較多,所以我們先將含有缺失值的變量篩選出來進行分析。
使用which函數將含有缺失值的列下標提取出來,然后將整個數據中含有缺失值的特征提取出來:
#首先載入需要用到的程序包 >library("dplyr") >library("mice") >library("ggthemes") >library("gridExtra") >library("ggplot2") >library("GGally") > > NAS<-which(colSums(is.na(HPdata))>0) > NASLotFrontage Alley MasVnrType MasVnrArea 4 7 26 27 BsmtQual BsmtCond BsmtExposure BsmtFinType1 31 32 33 34 BsmtFinType2 Electrical FireplaceQu GarageType 36 43 58 59 GarageYrBlt GarageFinish GarageQual GarageCond 60 61 64 65 PoolQC Fence MiscFeature 73 74 75 > NASdata<-HPdata[,NAS]然后對缺失的數據進行快速分類。缺失的數據分為兩種類型:
<1>MCAR:完全隨機缺失,指某個變量是否缺失與它本身的值無關,與其他任何變量的值也無關;
<2>MAR:隨機缺失,某個變量的缺失數據與其他觀測變量相關,與它自身的值無關。
<3>NIMAR:非隨機缺失:某個變量的缺失數據與其他觀測值及自身值都相關。
通常數據缺失的理想狀態為MCAR,假設數據缺失為此種類型,過多的數據丟失也是一個問題,一般缺失值比例的最大閾值為5%,若某些特征或樣本缺失值的數據缺失超過5%,那可能就需要忽略掉這些特征或樣本了,因此,我們先簡單看一下特征值缺失情況。
> NMiss<-function(x){sum(is.na(x))/length(x)*100} > apply(NASdata,2,NMiss)LotFrontage Alley MasVnrType MasVnrArea BsmtQual 17.73972603 93.76712329 0.54794521 0.54794521 2.53424658 BsmtCond BsmtExposure BsmtFinType1 BsmtFinType2 Electrical 2.53424658 2.60273973 2.53424658 2.60273973 0.06849315 FireplaceQu GarageType GarageYrBlt GarageFinish GarageQual 47.26027397 5.54794521 5.54794521 5.54794521 5.54794521 GarageCond PoolQC Fence MiscFeature 5.54794521 99.52054795 80.75342466 96.30136986 > NMiss<-function(x){sum(is.na(x))} > apply(NASdata,2,NMiss)LotFrontage Alley MasVnrType MasVnrArea BsmtQual BsmtCond BsmtExposure BsmtFinType1 BsmtFinType2 259 1369 8 8 37 37 38 37 38 Electrical FireplaceQu GarageType GarageYrBlt GarageFinish GarageQual GarageCond PoolQC Fence 1 690 81 81 81 81 81 1453 1179 MiscFeature 1406 >從上面的數據可以看到,有許多樣本的缺失值都超過了5%,甚至有的都達到了90%,如Alley、PoolQC等樣本,對于這些缺失較多的數據我們進行刪除處理。
這里也可以使用VIM包來對數據缺失的模式有一個更直觀的視覺展現。VIM包提供了大量可視化數據集中缺失值的函數,例如aggr(),matrixplot(),marginplot()。
> library("VIM") > aggr_plot<-aggr(NASdata,numbers=TRUE,sortVars=TRUE,labels=names(NASdata),cex.axis=.5, gap=3,ylab=c("Histogram of missing data","Pattern")) Variables sorted by number of missings: Variable CountPoolQC 0.9952054795MiscFeature 0.9630136986Alley 0.9376712329Fence 0.8075342466FireplaceQu 0.4726027397LotFrontage 0.1773972603GarageType 0.0554794521GarageYrBlt 0.0554794521GarageFinish 0.0554794521GarageQual 0.0554794521GarageCond 0.0554794521BsmtExposure 0.0260273973BsmtFinType2 0.0260273973BsmtQual 0.0253424658BsmtCond 0.0253424658BsmtFinType1 0.0253424658MasVnrType 0.0054794521MasVnrArea 0.0054794521Electrical 0.0006849315b)檢查分析導致數據缺失的原因
從上面的統計來看,PoolQC、MiscFeature、Alley、Fence等詞缺失量比較大,這里我們將數據缺失值超過5%的數據做刪除處理,另外從特征本身的字面意思來看,GarageType、GarageYrBlt、 GarageFinish、GarageQual、 GarageCond應該為相似特征,其缺失值的數量都相同,從數據來源的特征解釋中也可以看到,這些特征都是用來描述房子車庫的一些信息,而這些信息可以使用完整的數據特征GarageCars來表現了,因此對這五個特征進行刪除處理。
另外,對于BsmtExposure 、BsmtFinType2、BsmtQual 、 BsmtCond、BsmtFinType1 等特征從特征值來看,應該也為相似特征,從數據源特征描述可以看到,這些是用來描述地下室的一些特征信息,而關于地下室的信息特征總共有9個,其中四個是完整的數據信息,已足以表征basement(地下室)的特征信息了。
由此含有缺失值的特征就只剩下FireplaceQu、LotFrontage、MasVnrType、MasVnrArea 、Electrical。但從字面以及特征解釋中可以看到MasVnrType、MasVnrArea 有很高的相關性,同屬于描述外墻的特征,而且從上圖可以看出,它們缺失的實例完全相同,從字面意思來看其對房價的影響不太大,這里我們也做刪除處理。
總的來看,經過分析后,數據中剩下的包含缺失值的樣本目前就只剩下FireplaceQu、LotFrontage、Electrical。而在剩下的三個缺失值當中,FireplaceQu(壁爐質量)跟特征Fireplaces(壁爐數量)相關,當Fireplaces為0時,FireplaceQu(壁爐質量)為缺失值,因此對此缺失值的填補是無意義的。
c)刪除或補全缺失數據
根據上面的分析,先對整個數據中需要刪除的特征進行處理。
> NASdata1<-NASdata[,-which(colnames(NASdata)%in%c("LotFrontage","Electrical"))] > y<-which(colnames(HPdata)%in%colnames(NASdata1)) > HPdata1<-HPdata[,-y]現在數據集HPdata1中只包含LotFrontage、Electrical兩個含缺失值的特征了。從上面的分析可以看到,特征Electrical僅含有一個缺失值,因此這里就多Electrical進行簡單插補處理,取Eelectrial中的眾數SBrkr來填補。
> table(HPdata1[,"Electrical"]) FuseA FuseF FuseP Mix SBrkr 94 27 3 1 1334 > HPdata1[which(is.na(HPdata1[,"Electrical"])),"Electrical"]<-c("SBrkr") > table(HPdata1[,"Electrical"]) FuseA FuseF FuseP Mix SBrkr 94 27 3 1 1335 > sum(is.na(HPdata1[,"Electrical"])) [1] 0至此就只剩下一個特征LotFrontage存在缺失值。多重插補是在面對復雜缺失值問題時最常用的方法。這里我們使用mice包來填補LotFrontage缺失的數據。
> imp<-mice(HPdata1,m=5,method = "rf") > fit<-with(imp,lm(SalePrice~LotFrontage)) > pooled<-pool(fit) > summary(pooled)estimate std.error statistic df p.value (Intercept) 103864.930 7664.1623 13.55203 25.32757 4.121148e-13 LotFrontage 1099.599 105.4407 10.42860 22.52669 1.179994e-10 #這里對summary出來的參數值不是很明了,先暫且擱置 > HPdata2<-complete(imp,action = 3) > summary(HPdata2$LotFrontage)Min. 1st Qu. Median Mean 3rd Qu. Max. 21.00 59.75 70.00 70.14 80.00 313.00 > summary(HPdata$LotFrontage)Min. 1st Qu. Median Mean 3rd Qu. Max. NA's 21.00 59.00 69.00 70.05 80.00 313.00 2594)數據分析
現在我們得到了一個沒有缺失值的數據集HPdata2,接下來就來分析一下各個特征值與SalePrice之間的關系。首先將數據集中字符串型和數值型分開來進行分析。
F_obj1<-sapply(HPdata2,is.factor) > F_data<-HPdata2[,F_obj1,drop=FALSE]#或者HPdata2[which(sapply(HPdata2,is.factor))] > colnames(F_data)[1] "MSZoning" "Street" "LotShape" "LandContour" "Utilities" "LotConfig" "LandSlope" [8] "Neighborhood" "Condition1" "Condition2" "BldgType" "HouseStyle" "RoofStyle" "RoofMatl" [15] "Exterior1st" "Exterior2nd" "ExterQual" "ExterCond" "Foundation" "Heating" "HeatingQC" [22] "CentralAir" "Electrical" "KitchenQual" "Functional" "PavedDrive" "SaleType" "SaleCondition" > N_data<-HPdata2[which(sapply(HPdata2,is.numeric))] > names(N_data)[1] "Id" "MSSubClass" "LotFrontage" "LotArea" [5] "OverallQual" "OverallCond" "YearBuilt" "YearRemodAdd" [9] "BsmtFinSF1" "BsmtFinSF2" "BsmtUnfSF" "TotalBsmtSF" [13] "X1stFlrSF" "X2ndFlrSF" "LowQualFinSF" "GrLivArea" [17] "BsmtFullBath" "BsmtHalfBath" "FullBath" "HalfBath" [21] "BedroomAbvGr" "KitchenAbvGr" "TotRmsAbvGrd" "Fireplaces" [25] "GarageCars" "GarageArea" "WoodDeckSF" "OpenPorchSF" [29] "EnclosedPorch" "X3SsnPorch" "ScreenPorch" "PoolArea" [33] "MiscVal" "MoSold" "YrSold" "SalePrice"F_data中放置的為HPdata2中的字符串型數據,N_data中放置的為HPdata2中的數值型數據。
(1)數據可視化
首先通過數據可視化來了解一下各個特征值分布情況。對于離散型變量最直觀的就是條形圖,連續性變量可以使用折線圖來顯示。
#建立直方圖和密度圖函數 #直方圖函數 plotHist <- function(data_in, i) {data <- data.frame(x=data_in[[i]])p <- ggplot(data=data, aes(x=factor(x))) + stat_count() + xlab(colnames(data_in)[i]) + theme_light() + theme(axis.text.x = element_text(angle = 90, hjust =1))return (p) } #密度圖函數 plotDen <- function(data_in, i){data <- data.frame(x=data_in[[i]], SalePrice = data_in$SalePrice)p <- ggplot(data= data) + geom_line(aes(x = x), stat = 'density', size = 1,alpha = 1.0) +xlab(paste0((colnames(data_in)[i]), 'n', 'Skewness: ',round(skewness(data_in[[i]], na.rm = TRUE), 2))) + theme_light() return(p)} #建立直方圖或密度圖的調用函數 doPlots <- function(data_in, fun, ii, ncol=3) {pp <- list()for (i in ii) {p <- fun(data_in=data_in, i=i)pp <- c(pp, list(p))}do.call("grid.arrange", c(pp, ncol=ncol)) }使用直方圖對字符型特征變量進行圖形顯示。
> doPlots(F_data, fun = plotHist, ii = 1:8, ncol = 2)> doPlots(F_data, fun = plotHist, ii = 9:16, ncol = 2)> doPlots(F_data, fun = plotHist, ii = 17:24, ncol = 2)> doPlots(F_data, fun = plotHist, ii = 25:29, ncol = 2)繪制Neighborhood和SalePrice的箱線圖。
> ggplot(HPdata2, aes(x = Neighborhood, y = SalePrice)) + + geom_boxplot() + geom_hline(aes(yintercept=80), colour='red', linetype='dashed', lwd=2) + + scale_y_continuous() + + theme_few()從箱線圖上可以看出,BrkSide和OldTown以及SWISU地區附近有便宜的房子,而NridgHt和NoRidge有幾個高價異常值。
使用折線圖對數值型特征變量進行圖形顯示。從特征屬性及取值來看,'BedroomAbvGr', 'HalfBath', ' KitchenAbvGr','BsmtFullBath', 'BsmtHalfBath', 'MSSubClass'這幾特征雖然是數值型,但是其取值為有限的幾個常數值,因此使用直方圖會更加直觀。
> N_data1<-N_data[,-which(colnames(N_data)%in%c("BsmtFullBath", "BsmtHalfBath","FullBath","HalfBath","BedroomAbvGr","KitchenAbvGr"))] > N_data2<-N_data[,which(colnames(N_data)%in%c("BsmtFullBath", "BsmtHalfBath","FullBath","HalfBath","BedroomAbvGr","KitchenAbvGr"))] > doPlots(N_data1, fun = plotDen, ii = 2:7, ncol = 2)> doPlots(N_data1, fun = plotDen, ii = 8:13, ncol = 2)> doPlots(N_data1, fun = plotDen, ii = 14:19, ncol = 2)> doPlots(N_data1, fun = plotDen, ii = 20:29, ncol = 2)上面的密度圖可以看出所有的特征偏度均不為零。從YearBuilt的密度圖上可以看到,這次的統計數據中新老房子都有,這可能預示著由于住房危機,近年來房屋數量有所下降。
> doPlots(N_data2, fun = plotHist, ii = 1:6, ncol = 2)從上面的直方圖和密度圖我們可以看到原始的數據并不是標準的正態分布,我們需要優化這些數據,使其能夠按照機器學習的特性進行學習,我們先看一下房價與地面居住面積、地下室面積的散點圖。
ggplot(HPdata2,aes(y=SalePrice,x=GrLivArea))+geom_point()>ggplot(HPdata2,aes(y=SalePrice,x=TotalBsmtSF))+geom_point()從上面兩副散點圖可以看到,數據存在存在離群點,很顯然應該去掉。
> HPdata3<- HPdata2[(HPdata2$GrLivArea<=4000)&(HPdata2$TotalBsmtSF<=4000),]另外在上面進行數據展示的時候,可以看到數值型數據的偏度都比較大,并且曲線比較復雜,這里使用log(x+1)進行轉換,使數據線性化,這樣會方便后續數據處理和分析。
#把所有的數值型數據取出來 > N_data2<-HPdata3[which(sapply(HPdata3,is.numeric))] #計算每一個變量的偏度 > skew <- sapply(names(N_data2),function(x){skewness(N_data2[[x]],na.rm = T)}) #選擇一個偏度閾值,將超過閾值的變量進行轉換 > skew <- skew[skew > 0.75] > for(x in names(skew)) + { + HPdata3[[x]] <- log(HPdata3[[x]] + 1) + }接下來我們從上面產生的數據集中選出一組訓練集。
#設置訓練集觀測組數 > smp_size <- floor(0.75 * nrow(HPdata3)) #取出訓練集 > set.seed(123) > I_train <- sample(seq_len(nrow(HPdata3)), size = smp_size) > train_data<-HPdata3[I_train,] > validate<-HPdata3[-I_train,] #將Id特征從數據集中移除 > train_data <- subset(train_data,select=-c(Id))使用隨機森林建立訓練模型。
> library(randomForest) > house_model <- randomForest(SalePrice~.,data = train_data)查看變量重要性。
> importance <- importance(house_model) > varImpPlot(house_model)至此,訓練模型已經建立完成,可以將validate的數據集導入到模型中進行房價預測對比。
> P_validata<-validate > P_validata$SalePrice<-rep(NA,364) > prediction<-predict(house_model,P_validata) > hist(prediction) > hist(validate$SalePrice)從圖上看,預測結果和實際結果有一定的契合度,預測結果顯示房價區間在11到13之間,從實際房價來看的確有90%多的數據集中在11到13之間,并且大多數房價集中在11.5到12.5之間。
參考文獻:
Predicting House Prices using R?www.kaggle.comKaggle房價預測:數據預處理--練習 - qilixuening的博客 - CSDN博客?blog.csdn.net 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的kaggle房价预测特征意思_R语言实战:复杂数据处理和分析之Kaggle房价预测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 场效应与三极管 电路标识符_看懂这6个提
- 下一篇: activexobject对象不能创建_