使用sklearn進行數據挖掘-房價預測(5)—訓練模型


使用sklearn進行數據挖掘系列文章:

在前幾節,我們先對數據進行了解,然后又詳細介紹了數據集划分的方法,為了幫助我們更好的了解數據,又繪制了數據的分布圖,之后對數據進行了預處理(數值類型和標簽類型特征的處理)。上面這些步驟都是一些基礎工作,本節將介紹選擇和構建機器學習模型。

在測試集上面訓練模型###

經驗告訴我們,在使用機器學習算法的時候,一開始先選用簡單的模型,擼一個baseline是一個很好的習慣。所以我們先嘗試使用線性回歸模型,先使用幾個樣本嘗試以下該分類器:

from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(housing_prepared,housing_labels)
some_data = housing.iloc[:5]
some_labels = housing_labels.iloc[:5]
some_data_preared = full_pipeline.transform(some_data)
print 'prediction:',lin_reg.predict(some_data_preared)
print 'labels:',some_labels.values
>>
prediction: [ 210644.60459286  317768.80697211  210956.43331178   59218.9888684  189747.55849879]
labels: [ 286600.  340600.  196900.   46300.  254500.]

不錯,看來我們之前的一些預處理工作和分類器都能正常運行。那么我們該如何衡量我們的算法的好壞呢?
,sklearn提供了root mean squared error,RMSE作為評價指標:

from sklearn.metrics import mean_squared_error #

housing_predictions = lin_reg.predict(housing_prepared)
lin_mse = mean_squared_error(housing_labels,housing_predictions)
lin_rmse = np.sqrt(lin_mse) #平方根
print lin_rmse
>>
68628.1981985

從第一節housing.describe()中我們知道median_housing_values的范圍為14W-50W ,着也意味着分類器欠擬合訓練數據,我們需要做的是找一個能力更加強大的分類器或者減少對模型的約束。嘗試以下非線性回歸模型DecisionTreeRegressor,回歸決策樹能夠找出復雜的非線性關系,下面是代碼

from sklearn.tree import DecisionTreeRegressor 
tree_reg = DecisionTreeRegressor()
tree_reg.fit(housing_prepared,housing_labels)

housing_predictions = tree_reg.predict(housing_prepared)
tree_mse = mean_squared_error(housing_labels,housing_predictions)
tree_rmse = np.sqrt(tree_mse)
>>print tree_rmse
0.0

誤差竟然為0,實際上可能發生了嚴重的過擬合。那么問題來了,我們該如何分析結果到底是欠擬合還是過擬合呢?下面就引入了交叉驗證

交叉驗證###

由於目前我們的測試集是不能動的,因為還沒到確定最終的模型。我們可以把訓練集再划分為訓練集和測試集兩部分。我們可以使用前面提到的train_test_split方法,不過強大的sklearn還提供了K-fold交叉驗證方法:

from sklearn.model_selection import cross_val_score
scores = cross_val_score(tree_reg,housing_prepared,\
        housing_labels,scoring='neg_mean_squared_error',cv=10)
rmse_scores = np.sqrt(-scores)

上面這段代碼將訓練集隨機的分為10份,在9份上面訓練,在剩下的一份上面測試。

>>rmse_scores 
array([ 69080.4167045 ,  67652.35297369,  70592.30099278,  67905.0445584 ,
        71256.61551091,  74264.47020443,  70141.37468916,  71525.02444872,
        76283.57397045,  69691.77150094])
>>rmse_scores.mean()
70839.294555398083
>>rmse_scores.std()
2564.0079357717691

note:sklearn提供的交叉驗證方法希望得到一個較大的值(越大越好),這個和損失函數正好相反(越小越好),所以使用的是-score
看到了上面的結果,發現決策是的效果其實很一般,甚至還沒有線性回歸的結果好(增加了3K)。
現在看以下線性回歸的交叉驗證值

lin_scores = cross_val_score(lin_reg,housing_prepared,\
            housing_labels,scoring='neg_mean_squared_error',cv=10)
lin_rmse_scores = np.sqrt(-lin_scores)
>>lin_rmse_scores 
array([ 66782.73843989,  66960.118071  ,  70347.95244419,  74739.57052552,
        68031.13388938,  71193.84183426,  64969.63056405,  68281.61137997,
        71552.91566558,  67665.10082067])
>>lin_rmse_scores.mean()
69052.461363450828
>>lin_rmse_scores.std()
2731.6740017983493

使用隨機森林(RandomForestRegression)

from sklearn.ensemble import RandomForestRegressor
forest_reg = RandomForestRegressor()
forest_reg.fit(housing_prepared, housing_labels)
housing_predictions = forest_reg.predict(housing_prepared)
forest_mse = mean_squared_error(housing_labels, housing_predictions)
forest_rmse = np.sqrt(forest_mse)
print forest_rmse #22180.0543101
forest_scores = cross_val_score(forest_reg, housing_prepared, housing_labels,
                                scoring="neg_mean_squared_error", cv=10)
forest_rmse_scores = np.sqrt(-forest_scores)
>>forest_rmse_scores 
array([ 52036.18016789,  51138.17643755,  54179.12437821,  53870.89837397,
        52413.73419948,  55299.52908533,  51322.32440328,  50743.46362248,
        55491.68139413,  52746.07818231])
>>forest_rmse_scores.mean() #結果大於22180。說明訓練集存在過擬合
52924.119024463616
>>forest_rmse_scores.std()
1621.653495429834

上面列舉了使用線性回歸、決策樹回歸和隨機森林回歸的方法。可以看的出隨機森林的效果最好,如果你想還可以繼續嘗試其他的算法比如SVR、神經網絡等,找出效果較好的模型。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM