基于北京二手房价数据的探索性数据分析和房价评估——房价评估模型构建
數(shù)據(jù)分析項目——北京二手房價數(shù)據(jù)分析
- 第一步:項目設(shè)計和獲取數(shù)據(jù)(獲取實驗的數(shù)據(jù)集!!)
- 第二步:數(shù)據(jù)讀取和數(shù)據(jù)預(yù)處理
- 第三步:數(shù)據(jù)的可視化分析
- 第四步:構(gòu)建房價評估模型(決策樹、隨機(jī)森林等)
整個項目的代碼和數(shù)據(jù)集獲取:
https://github.com/Proberen/Data-analysis___Beijing__Houseprice
文章目錄
- 1 數(shù)據(jù)預(yù)處理
- 1.1 分解戶型列
- 1.2 特征選取
- 1.3 分類數(shù)據(jù)轉(zhuǎn)換
- 2 數(shù)據(jù)特征相關(guān)性分析
- 3 建立模型
- 3.1 劃分?jǐn)?shù)據(jù)集
- 3.2 決策樹模型
- 學(xué)習(xí)曲線
- 構(gòu)建模型
- 決策樹可視化
- 3.3 隨機(jī)森林
- 學(xué)習(xí)曲線
- 構(gòu)建模型
- 3.4 k-近鄰模型
- 4 測試
- 4.1 測試用例
- 4.2 測試
1 數(shù)據(jù)預(yù)處理
1.1 分解戶型列
通過上述分析,可以發(fā)現(xiàn)戶型與房屋總價具有關(guān)聯(lián)性,由于該列的數(shù)據(jù)存在中文,且戶型多樣,因此需要進(jìn)行處理。
共添加7列,包括別墅列、車位列、室列、廳列等。分解戶型列的代碼如下:
1、初始化添加列
data.loc[:,'BigHouse0'] = 0 data.loc[:,'BigHouse1'] = 0 data.loc[:,'BigHouse2'] = 0 data.loc[:,'BigHouse3'] = 0 data.loc[:,'car'] = 0 data.loc[:,'room'] = 0 data.loc[:,'office'] = 02、別墅列、車位列賦值
data=data.copy() for i in range(len(data)):if data.at[i,'HouseType']==' 疊拼別墅 ':data.at[i,'HouseType'] = 0data.at[i,'BigHouse0'] = 1if data.at[i,'HouseType']==' 聯(lián)排別墅 ':data.at[i,'HouseType'] = 1 data.at[i,'BigHouse1'] = 1if data.at[i,'HouseType']==' 獨棟別墅 ':data.at[i,'HouseType'] = 2data.at[i,'BigHouse2'] = 1if data.at[i,'HouseType']==' 雙拼別墅 ':data.at[i,'HouseType'] = 3data.at[i,'BigHouse3'] = 1if data.at[i,'HouseType']==' 車位 ':data.at[i,'HouseType']= 4data.at[i,'car'] = 13、定義分解室、廳函數(shù)
# 定義分解函數(shù) def apart_room(x):if x == 0:return 0if x == 1:return 0if x == 2:return 0if x == 3:return 0if x == 4:return 0room = x.split('室')[0]return int(room)def apart_hall(x):if x == 0:return 0if x == 1:return 0if x == 2:return 0if x == 3:return 0if x == 4:return 0hall = x.split('廳')[0].split('室')[1]return int(hall)4、室、廳列賦值
# 給room、office列賦值 data['room'] = data['HouseType'].map(apart_room) data['office'] = data['HouseType'].map(apart_hall)1.2 特征選取
在進(jìn)行建模前,需要根據(jù)數(shù)據(jù)可視化分析的結(jié)果進(jìn)行特征的選取,在本階段,選取面積、戶型、總價、城區(qū)、發(fā)布時間為特征,刪除多余特征列。
# 刪除戶型、單價、簡介、小區(qū)列 newdata = data.copy() newdata.drop(columns=['HouseType','Price','Introduction','Quarters','Lotitude','Longitude','Latitude','PeopleNumber','WatchNumber'],inplace=True)1.3 分類數(shù)據(jù)轉(zhuǎn)換
由于需要城區(qū)列中含有中文,城區(qū)為分類數(shù)據(jù),根據(jù)下列代碼將城區(qū)轉(zhuǎn)換為數(shù)字。
labels = newdata['Dist'].unique().tolist() newdata['Dist'] = newdata['Dist'].apply(lambda x :labels.index(x))轉(zhuǎn)換后的數(shù)據(jù)預(yù)覽如下圖所示:
2 數(shù)據(jù)特征相關(guān)性分析
在建模前,對數(shù)據(jù)特征進(jìn)行相關(guān)行分析,構(gòu)建相關(guān)性矩陣熱力圖如下圖所示,通過觀察下圖可以發(fā)現(xiàn),面積、戶型等特征與房屋總價的相關(guān)性都大于0.6,為重要的特征因素。
plt.figure(figsize=(10,10)) sns.heatmap(newdata.corr(),cmap="YlGnBu",linewidths=0.1,vmax=1.0,square=True,linecolor= 'white',annot=True) plt.title('特征相關(guān)性熱力圖',size=20) plt.show()3 建立模型
3.1 劃分?jǐn)?shù)據(jù)集
將數(shù)據(jù)集中的20%作為訓(xùn)練集,80%作為測試集,劃分?jǐn)?shù)據(jù)集的代碼如下:
from sklearn.model_selection import train_test_split from sklearn import tree from sklearn.tree import DecisionTreeRegressor from sklearn.model_selection import cross_val_score import graphviz from sklearn.preprocessing import PolynomialFeatures from sklearn.ensemble import RandomForestRegressor from sklearn.neighbors import KNeighborsRegressor features = newdata.iloc[:,newdata.columns != 'TotalPrice'] target = newdata.iloc[:,newdata.columns == 'TotalPrice']#劃分?jǐn)?shù)據(jù)集 features_train,features_test,target_train,target_test= train_test_split(features,target,test_size=0.2,random_state=25)for i in [features_train,features_test,target_train,target_test]:i.index = range(i.shape[0])3.2 決策樹模型
學(xué)習(xí)曲線
tr=[] te=[] tc=[] N=10 for i in range(10):clf = DecisionTreeRegressor(random_state=25,max_depth=i+1,criterion='mse')clf=clf.fit(features_train,target_train)score_tr = clf.score(features_train,target_train)score_te = clf.score(features_test,target_test)score_tc = cross_val_score(clf,features,target,cv=10).mean()tr.append(score_tr)te.append(score_te)tc.append(score_tc)print(max(te)) print(max(tc))plt.figure(figsize=(20,10)) plt.plot(range(1,N+1),tr,color='red',label='train') plt.plot(range(1,N+1),te,color='blue',label='test') plt.plot(range(1,N+1),tc,color='green',label='cross') plt.xticks(range(1,N+1)) plt.legend() plt.xlabel("max_depth",size=20) plt.ylabel("score",size=20) plt.title('決策樹學(xué)習(xí)曲線',size=20) plt.show()決策樹的學(xué)習(xí)曲線如下圖所示,在max_depth為7時交叉驗證的得分最高,得分最高為0.59
構(gòu)建模型
根據(jù)學(xué)習(xí)曲線,構(gòu)建決策樹模型,決策樹的測試集得分為0.74,交叉驗證得分為0.59,說明該模型的擬合度較高
dt = DecisionTreeRegressor(max_depth=7,random_state=25) dt=dt.fit(features_train,target_train) print(f'訓(xùn)練集得分:{round(dt.score(features_train,target_train),5)}') print(f'測試集得分:{round(dt.score(features_test,target_test),5)}') print(f'交叉驗證得分:{round(cross_val_score(dt,features,target.values.ravel(),cv=10).mean(),5)}')決策樹可視化
feature_name = ['面積','發(fā)布時間','區(qū)域','別墅0','別墅1','別墅2','別墅3','車庫','室','廳']import graphvizdot_data = tree.export_graphviz(dt,out_file = None,feature_names = feature_name,class_names=['a','b','c'],filled=True,rounded=True) graph = graphviz.Source(dot_data) graph.save('./graph/tree.dot') graph3.3 隨機(jī)森林
學(xué)習(xí)曲線
tr=[] te=[] tc=[] N=10 for i in range(10):clf = RandomForestRegressor(random_state=25,max_depth=i+1,criterion='mse')clf=clf.fit(features_train,target_train.values.ravel())score_tr = clf.score(features_train,target_train)score_te = clf.score(features_test,target_test)score_tc = cross_val_score(clf,features,target.values.ravel(),cv=10).mean()tr.append(score_tr)te.append(score_te)tc.append(score_tc)print(max(te)) print(max(tc))plt.figure(figsize=(20,10)) plt.plot(range(1,N+1),tr,color='red',label='train') plt.plot(range(1,N+1),te,color='blue',label='test') plt.plot(range(1,N+1),tc,color='green',label='cross') plt.xticks(range(1,N+1)) plt.legend() plt.xlabel("max_depth",size=20) plt.ylabel("score",size=20) plt.title('隨機(jī)森林學(xué)習(xí)曲線',size=20) plt.show()隨機(jī)森林的學(xué)習(xí)曲線如下圖所示,在max_depth為10時交叉驗證的得分最高,得分最高為0.68
構(gòu)建模型
rf = RandomForestRegressor(n_estimators=100,max_depth=10) rf.fit(features_train,target_train.values.ravel()) print(f'訓(xùn)練集得分:{round(rf.score(features_train,target_train),5)}') print(f'測試集得分:{round(rf.score(features_test,target_test),5)}') print(f'交叉驗證得分:{round(cross_val_score(rf,features,target.values.ravel(),cv=10).mean(),5)}')3.4 k-近鄰模型
構(gòu)建該組數(shù)據(jù)的k-近鄰模型如下所示,測試集得分表現(xiàn)較差,僅為0.57。準(zhǔn)確率不如決策樹和隨機(jī)森林。
4 測試
4.1 測試用例
本次測試選取測試用例為30天前發(fā)布的面積為100平米西城區(qū)2室2廳的二手房
apply = np.array([100,30,1,0,0,0,0,0,2,2]).reshape(1,-1)4.2 測試
print('------------總價預(yù)測結(jié)果-------------') print(f'隨機(jī)森林回歸:{rf.predict(apply)[0]}萬元') print(f'決策樹回歸:{dt.predict(apply)[0]}萬元') print(f'K近鄰回歸:{kn.predict(apply)[0][0]}萬元') print('------------綜合預(yù)測結(jié)果-------------') print(((rf.predict(apply)+dt.predict(apply)+kn.predict(apply))/3.0)[0][0],'萬元')總結(jié)
以上是生活随笔為你收集整理的基于北京二手房价数据的探索性数据分析和房价评估——房价评估模型构建的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dev C++,一个好玩的猜数字游戏
- 下一篇: OAD 空中升级