日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

广州二手房价分析与预测

發(fā)布時(shí)間:2023/12/8 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 广州二手房价分析与预测 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、概述

?

1.1問題介紹與分析

隨著社會(huì)經(jīng)濟(jì)的迅猛發(fā)展,房地產(chǎn)開發(fā)建設(shè)的速度越來越快,二手房市場迅猛發(fā)展,對二手房房產(chǎn)價(jià)格評估的需求也隨之增大.因此,對二手房房價(jià)預(yù)測與分析是必要的.詳細(xì)文檔與代碼資料保存在我的百度云盤。

數(shù)據(jù)收集:在鏈家網(wǎng)站上收集廣州二手房數(shù)據(jù),把數(shù)據(jù)分為訓(xùn)練集、測試集。訓(xùn)練和測試數(shù)據(jù)是一些二手房信息以及價(jià)格狀況,要嘗試根據(jù)它生成合適的模型并預(yù)測其他二手房的價(jià)格狀況。這是一個(gè)回歸問題,很多回歸算法都可以解決。

收集工具:八爪魚

?

?

1.2總體思路

首先從數(shù)據(jù)清洗開始,對缺失值的多維度處理、對離群點(diǎn)的剔除方法以及對字符、空格等的處理;其次進(jìn)行特征工程,包括類別特征編碼、連續(xù)特征編碼等;再次進(jìn)行特征選擇,采用了xgboost,xgboost的訓(xùn)練過程即對特征重要性的排序過程;最后一部分是模型設(shè)計(jì)與分析,采用了嶺回歸模型、xgboost,取得了不錯(cuò)的效果,此外還介紹了模型融合方法。

?

二、 數(shù)據(jù)清洗

?

2.1缺失值的多維度處理

1)通常遇到缺值的情況,我們會(huì)有幾種常見的處理方式

①如果缺值的樣本占總數(shù)比例極高,我們可能就直接舍棄了,作為特征加入的話,可能反倒帶入noise,影響最后的結(jié)果了

②如果缺值的樣本適中,而該屬性非連續(xù)值特征屬性(比如說類目屬性),那就把NaN作為一個(gè)新類別,加到類別特征中

③如果缺值的樣本適中,而該屬性為連續(xù)值特征屬性,有時(shí)候我們會(huì)考慮給定一個(gè)step(比如這里的age,我們可以考慮每隔2/3歲為一個(gè)步長),然后把它離散化,之后把NaN作為一個(gè)type加到屬性類目中。

2)有些情況下,缺失的值個(gè)數(shù)并不是特別多,那我們也可以試著根據(jù)已有的值,擬合一下數(shù)據(jù),補(bǔ)充上。



2.2數(shù)據(jù)預(yù)處理

#載入數(shù)據(jù):

train=pd.read_csv('train.csv')

test= pd.read_csv('test.csv')


#檢視源數(shù)據(jù)

print(train.head())

?

#合并數(shù)據(jù)

這么做主要是為了用DF進(jìn)行數(shù)據(jù)預(yù)處理的時(shí)候更加方便。等所有的需要的預(yù)處理進(jìn)行完之后,我們再把他們分隔開。

首先,價(jià)格作為我們的訓(xùn)練目標(biāo),只會(huì)出現(xiàn)在訓(xùn)練集中,不會(huì)在測試集中。所以,我們先把價(jià)格這一列給拿出來。

?

#可視化價(jià)格特征

prices= pd.DataFrame({"price":train["價(jià)格"],"log(price + 1)":np.log1p(train["價(jià)格"])})

prices.hist()

#可見,label本身并不平滑。為了分類器的學(xué)習(xí)更加準(zhǔn)確,首先把label給“平滑化”(正態(tài)化)

#這里使用log1p, 也就是 log(x+1),避免了復(fù)值的問題。值得注意的是,如果這里把數(shù)據(jù)都給平滑化了,那么最后算結(jié)果的時(shí)候,要把預(yù)測到的平滑數(shù)據(jù)給變回去。按照“怎么來的怎么去”原則,log1p()就需要expm1(); 同理,log()就需要exp()

?

y_train= np.log1p(train.pop('價(jià)格'))

#然后把剩下的部分合并起來?????

all_df= pd.concat((train, test), axis=0)

?

三、特征工程

?

#變量轉(zhuǎn)換

all_df["樓齡"]=2017-all_df["樓齡"]

#有一些數(shù)據(jù)是缺失的,根據(jù)缺失值的多少進(jìn)行相應(yīng)的處理

#查看缺失情況

print(all_df.isnull().sum().sort_values(ascending=False).head(10))

#可以看到,缺失最多的column是裝修情況。由于裝修情況的值缺失太多就刪掉這一列

all_df.pop("裝修情況")

?

#接著處理樓齡的缺失值,由于缺失不多,這里我用平均值進(jìn)行填充

mean_col= all_df["樓齡"].mean()

all_df["樓齡"]=all_df["樓齡"].fillna(mean_col)

?

#由于變量交易權(quán)屬 建筑類型 配備電梯的絕大多數(shù)的值相同,區(qū)分的效果不會(huì)很明顯這里就刪掉了

all_df.pop("建筑類型")

all_df.pop("配備電梯")

all_df.pop("交易權(quán)屬")

#該特征很多都不相同,這里簡單處理就刪掉了

all_df.pop("房型")

?

#看看是不是沒有空缺了?

print(all_df.isnull().sum().sum())

?

#把category的變量轉(zhuǎn)變成numerical表達(dá)形式

#當(dāng)我們用numerical來表達(dá)categorical的時(shí)候,要注意,數(shù)字本身有大小的含義所以亂用數(shù)字會(huì)給之后的模型學(xué)習(xí)帶來麻煩。于是我們可以用One-Hot的方法來表達(dá)category。pandas自帶的get_dummies方法可以幫你一鍵做到One-Hot。

pd.get_dummies(all['區(qū)域'], prefix='區(qū)域')

#此刻區(qū)域被分成了5個(gè)column,每一個(gè)代表一個(gè)category。是就是1,不是就是0。

#同理,我們把所有的category數(shù)據(jù),都給One-Hot了

all_dummy_df= pd.get_dummies(all_df)

?

#標(biāo)準(zhǔn)化numerical數(shù)據(jù)

#這一步并不是必要,但是得看你想要用的分類器是什么。一般來說,regression的分類器最好是把源數(shù)據(jù)給放在一個(gè)標(biāo)準(zhǔn)分布內(nèi)。不要讓數(shù)據(jù)間的差距太大。這里,我們當(dāng)然不需要把One-Hot的那些0/1數(shù)據(jù)給標(biāo)準(zhǔn)化。我們的目標(biāo)應(yīng)該是那些本來就是numerical的數(shù)據(jù):

?

#先來看看哪些是numerical的:

numeric_cols= all_df.columns[all_df.dtypes != 'object']

#這里也是用log1p()方法進(jìn)行平滑

all_dummy_df["樓齡"]=np.log1p(all_dummy_df["樓齡"])

all_dummy_df["建筑面積"]=np.log1p(all_dummy_df["建筑面積"])

?

四、 特征選擇

?

在特征工程部分,這么多維特征一方面可能會(huì)導(dǎo)致維數(shù)災(zāi)難,另一方面很容易導(dǎo)致過擬合,需要做降維處理,降維方法常用的有如 PCA,t-SNE 等,這類方法的計(jì)算復(fù)雜度比較高。并且根據(jù)以往經(jīng)驗(yàn),PCA 或t-SNE 效果往往不好。除了采用降維算法之外,也可以通過特征選擇來降低特征維度。特征選擇的方法很多:最大信息系數(shù)(MIC)、皮爾森相關(guān)系數(shù)(衡量變量間的線性相關(guān)性)、正則化方法(L1,L2)、基于模型的特征排序方法。比較高效的是最后一種,即基于學(xué)習(xí)模型的特征排序方法,這種方法有一個(gè)好處:模型學(xué)習(xí)的過程和特征選擇的過程是同時(shí)進(jìn)行的,因此我們采用這種方法,基于xgboost 來做特征選擇,xgboost 模型訓(xùn)練完成后可以輸出特征的重要性,據(jù)此我們可以保留Top N 個(gè)特征,從而達(dá)到特征選擇的目的。

?

五、 模型設(shè)計(jì)與分析

?

5.1單個(gè)分類器

從訓(xùn)練數(shù)據(jù)中隨機(jī)劃分部分?jǐn)?shù)據(jù)作為驗(yàn)證集,剩下作為訓(xùn)練集,供模型調(diào)參使用。在訓(xùn)練集上采用十折交叉驗(yàn)證進(jìn)行模型調(diào)參。得到多個(gè)單模型結(jié)果后,再在驗(yàn)證集上做進(jìn)一步的模型融合。

#把數(shù)據(jù)集分回訓(xùn)練/測試集

dummy_train_df= all_dummy_df[:110]

dummy_test_df= all_dummy_df[110:-1]

X_train= dummy_train_df.values

X_test= dummy_test_df.values

(1)隨機(jī)森林

max_features= [.1, .3, .5, .7, .9, .99]

test_scores= []

formax_feat in max_features:

??? clf =RandomForestRegressor(n_estimators=200, max_features=max_feat)

??? test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=5, scoring='neg_mean_squared_error'))

??? test_scores.append(np.mean(test_score))

plt.plot(max_features,test_scores)

plt.title("MaxFeatures vs CV Error");

#用RF的最優(yōu)值達(dá)到了0.194

?

(2)這里我們用一個(gè)Stacking的思維來汲取兩種或者多種模型的優(yōu)點(diǎn)首先,我們把最好的parameter拿出來,

做成我們最終的model

ridge= Ridge(alpha=1)

rf= RandomForestRegressor(n_estimators=500, max_features=.3)

ridge.fit(X_train,y_train)

rf.fit(X_train,y_train)

#上面提到了,因?yàn)樽钋懊嫖覀兘olabel做了個(gè)log(1+x), 這里我們需要把predit的值給exp回去,并且減掉那個(gè)"1"

所以就是我們的expm1()函數(shù)。

y_ridge= np.expm1(ridge.predict(X_test))

y_rf= np.expm1(rf.predict(X_test))

#一個(gè)正經(jīng)的Ensemble是把這群model的預(yù)測結(jié)果作為新的input,再做一次預(yù)測。

y_final= 0.8*y_ridge + 0.2*y_rf

print(y_final)

?

要判定一下當(dāng)前模型所處狀態(tài)(欠擬合or過擬合)

?

有一個(gè)很可能發(fā)生的問題是,我們不斷地做feature engineering,產(chǎn)生的特征越來越多,用這些特征去訓(xùn)練模型,會(huì)對我們的訓(xùn)練集擬合得越來越好,同時(shí)也可能在逐步喪失泛化能力,從而在待預(yù)測的數(shù)據(jù)上,表現(xiàn)不佳,也就是發(fā)生過擬合問題。從另一個(gè)角度上說,如果模型在待預(yù)測的數(shù)據(jù)上表現(xiàn)不佳,除掉上面說的過擬合問題,也有可能是欠擬合問題,也就是說在訓(xùn)練集上,其實(shí)擬合的也不是那么好。而在機(jī)器學(xué)習(xí)的問題上,對于過擬合和欠擬合兩種情形。我們優(yōu)化的方式是不同的。

?

對過擬合而言,通常以下策略對結(jié)果優(yōu)化是有用的:

  • 做一下feature selection,挑出較好的feature的subset來做training
  • 提供更多的數(shù)據(jù),從而彌補(bǔ)原始數(shù)據(jù)的bias問題,學(xué)習(xí)到的model也會(huì)更準(zhǔn)確

而對于欠擬合而言,我們通常需要更多的feature,更復(fù)雜的模型來提高準(zhǔn)確度。

著名的learning curve可以幫我們判定我們的模型現(xiàn)在所處的狀態(tài)。我們以樣本數(shù)為橫坐標(biāo),訓(xùn)練和交叉驗(yàn)證集上的錯(cuò)誤率作為縱坐標(biāo),兩種狀態(tài)分別如下兩張圖所示:過擬合,欠擬合

?

著名的learningcurve可以幫我們判定我們的模型現(xiàn)在所處的狀態(tài)。我們以樣本數(shù)為橫坐標(biāo),訓(xùn)練和交叉驗(yàn)證集上的錯(cuò)誤率作為縱坐標(biāo)

在實(shí)際數(shù)據(jù)上看,我們得到的learning curve沒有理論推導(dǎo)的那么光滑,但是可以大致看出來,訓(xùn)練集和交叉驗(yàn)證集上的得分曲線走勢還是符合預(yù)期的。目前的曲線看來,我們的model并不處于overfitting的狀態(tài)(overfitting的表現(xiàn)一般是訓(xùn)練集上得分高,而交叉驗(yàn)證集上要低很多,中間的gap比較大)。

?

5.2 Bagging

?

一般來說,單個(gè)分類器的效果真的是很有限。我們會(huì)傾向于把N多的分類器合在一起,做一個(gè)“綜合分類器”以達(dá)到最好的效果。模型融合可以比較好地緩解,訓(xùn)練過程中產(chǎn)生的過擬合問題,從而對于結(jié)果的準(zhǔn)確度提升有一定的幫助。Bagging把很多的小分類器放在一起,每個(gè)train隨機(jī)的一部分?jǐn)?shù)據(jù),然后把它們的最終結(jié)果綜合起來(多數(shù)投票制)。Sklearn已經(jīng)直接提供了這套構(gòu)架,我們直接調(diào)用就行:在這里,我們用CV結(jié)果來測試不同的分類器個(gè)數(shù)對最后結(jié)果的影響。注意,我們在部署B(yǎng)agging的時(shí)候,要把它的函數(shù)base_estimator里填上你的小分類器

?

(1)用bagging自帶的DT

params= [1, 10, 15, 20, 25, 30, 40]

test_scores= []

forparam in params:

clf= BaggingRegressor(n_estimators=param)

?test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=10, scoring='neg_mean_squared_error'))

test_scores.append(np.mean(test_score))

???

plt.plot(params,test_scores)

plt.title("n_estimatorvs CV Error");

#用bagging自帶的DT,結(jié)果是0.196

?

(2)ridge + bagging

ridge= Ridge(1)

params= [1, 10, 15, 20, 25, 30, 40]

test_scores= []

forparam in params:

??? clf = BaggingRegressor(n_estimators=param,base_estimator=ridge)

??? test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=10, scoring='neg_mean_squared_error'))

??? test_scores.append(np.mean(test_score))

plt.plot(params,test_scores)

print(test_scores)

plt.title("n_estimatorvs CV Error");

?

#使用25個(gè)小ridge分類器的bagging,達(dá)到了0.163的結(jié)果.

#learning_curve曲線,準(zhǔn)確率比較高,基本沒有過擬合

?

5.3Boosting

#Boosting比Bagging理論上更高級點(diǎn),它也是攬來一把的分類器。但是把他們線性排列。下一個(gè)分類器把上一個(gè)分類器分類得不好的地方加上更高的權(quán)重,這樣下一個(gè)分類器就能在這個(gè)部分學(xué)得更加“深刻”。

?

(1)Adaboost+Ridge

params= [34,35,36,45,50,55,60,65]

test_scores= []

forparam in params:

??? clf = AdaBoostRegressor(n_estimators=param,base_estimator=ridge)

??? test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=10, scoring='neg_mean_squared_error'))

??? test_scores.append(np.mean(test_score))

plt.plot(params,test_scores)

plt.title("n_estimatorvs CV Error");??

#Adaboost+Ridge在這里,55個(gè)小分類器的情況下,達(dá)到了0.163的結(jié)果。其learning_curve曲線如下:

?

(2)使用Adaboost自帶的DT

params= [10, 15, 20, 25, 30, 35, 40, 45, 50]

test_scores= []

forparam in params:

??? clf = AdaBoostRegressor(n_estimators=param)

??? test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=10, scoring='neg_mean_squared_error'))

??? test_scores.append(np.mean(test_score))

plt.plot(params,test_scores)

plt.title("n_estimatorvs CV Error");

#test_scores達(dá)到0.198的結(jié)果

?

5.3XGBoost

#這依舊是一個(gè)Boosting框架的模型,但是卻做了很多的改進(jìn)。用Sklearn自帶的cross validation方法來測試模型

params= [1,2,3,4,5,6]

test_scores= []

forparam in params:

??? clf = XGBRegressor(max_depth=param)

??? test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=10, scoring='neg_mean_squared_error'))

??? test_scores.append(np.mean(test_score))

?

plt.plot(params,test_scores)

plt.title("max_depthvs CV Error");

#當(dāng)params值為6時(shí),test_scores達(dá)到0.185

#輕微過擬合

?

5.4 GBM

params= [80,90,100,110,120,130,140,150]

test_scores= []

forparam in params:

??? clf =GradientBoostingRegressor(n_estimators=param)

??? test_score = np.sqrt(-cross_val_score(clf,X_train, y_train, cv=10, scoring='neg_mean_squared_error'))

??? test_scores.append(np.mean(test_score))

???

plt.plot(params,test_scores)

plt.title("max_depthvs CV Error");

?

#當(dāng)params值為90時(shí),test_scores達(dá)到0.188,從其學(xué)習(xí)率曲線可以看出,模型過擬合挺嚴(yán)重

#綜上,Bagging + Ridge 與Adaboost+Ridge模型的準(zhǔn)確率和泛化能力是比較好。



六 使用ridge + bagging模型預(yù)測房價(jià)

?

ridge= Ridge(1)

br=BaggingRegressor(n_estimators=param, base_estimator=ridge)

br.fit(X_train,y_train)

#房價(jià)預(yù)測

y_br= np.expm1(br.predict(X_test))

?

features={'樓齡' , '建筑面積' , '區(qū)域_增城' , '區(qū)域_天河' , '區(qū)域_海珠’, '區(qū)域_番禺' , '區(qū)域_白云' ,? '樓層_中樓層' , '樓層_低樓層' , '樓層_獨(dú)棟' , '樓層_高樓層' , '朝向_東' , '朝向_東北' , '朝向_東南' , '朝向_東西' , '朝向_北' , '朝向_南' , '朝向_南北' , '朝向_西' , '朝向_西北' , '朝向_西南' , '房屋用途_別墅' , '房屋用途_普通住宅'}???

?

#使用GBM模型進(jìn)行特征選擇

gbr= GradientBoostingRegressor(loss='ls', n_estimators=100, max_depth=3,verbose=1, warm_start=True)

gbr_fitted= gbr.fit(X_train, y_train)

?

#查看特征重要度,根據(jù)特征重要度可以進(jìn)行特征選擇,選取重要度高的特征,刪除不重要的特征以減少維度降低過擬合

print(zip(features,list(gbr.feature_importances_)))

#可見建筑面積是影響房屋價(jià)格的最重要特征。

總結(jié)

以上是生活随笔為你收集整理的广州二手房价分析与预测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。