我參加的第一場Kaggle競賽!

評估指標

評估指標是RMSLE(均方根對數誤差),因此在這種情況下獲取因變量(即SalePrice)的日誌是有意義的。

我參加的第一場Kaggle競賽!

數據解釋

你可能已經注意到"Alley"列的前六行都是NaN值(描述了相應行的缺失數據)。因此,讓我們找出所有特徵的整個數據集中缺失值的百分比。

我參加的第一場Kaggle競賽!

我參加的第一場Kaggle競賽!

缺少數據的列

我們有5個特徵,Nan%大於50。很可能這些特徵不會為我們提供有關數據集的任何有用的見解,所以我們現在可以考慮刪除它們,但我們將很快看到特徵重要性無論如何,讓我們暫時保留它們,讓隨機森林為我們做出這個決定。

數據清理

為了將此數據集提供給隨機森林,我們必須將所有非數值數據轉換為數值數據。所有非數字數據列都代表兩種類型的分類數據:

序數(Ordinal):類別的順序很重要。

名義(Nominal):順序無關緊要。

有兩種方法可以將這些轉換為數字:

標籤編碼:用整數標籤替換類別,範圍從0到(類別數-1)。它使得分類數據按順序排列。

One-Hot編碼:將具有分類數據的一列拆分為多列(等於類別數)。數字由1和0替換,具體取決於哪個列具有什麼值。

有關Label vs One-hot編碼的更多信息,可以查看這篇文章。 https://medium.com/@contactsunny/label-encoder-vs-one-hot-encoder-in-machine-learning-3fc273365621

無論如何,大多數列都是具有順序的,所以我們將對這個數據集使用標籤編碼(稍後嘗試了One-Hot編碼,它將我的RMSLE增加了0.01)。"train_cats"和"proc_df"取自Github上的fastai repo。如果需要,你可以查看源代碼和文檔。

我參加的第一場Kaggle競賽!

https://github.com/fastai/fastai/blob/master/old/fastai/structured.py

我們還用相應列的中位數替換了數值數據列的缺失值,並添加了{name} _na列 它指定數據是否丟失。

查看這些數據,我發現沒有任何特徵能夠告訴住宅的房齡是多少,所以我將其添加到另一個可以提供住宅總居住面積的特徵中。

我參加的第一場Kaggle競賽!

拆分訓練集和驗證集

構建隨機森林之前的最後一件事是將我們的數據集劃分為兩部分:訓練集和驗證集。可能機器學習中最重要的想法是擁有單獨的訓練和驗證數據集。作為動機,假設你不劃分數據,而是使用所有數據。假設你有很多參數:

我參加的第一場Kaggle競賽!

對於最右側的模型,圖示數據點的誤差最小(藍色曲線幾乎完美地穿過紅點),但它不是最佳選擇。這是為什麼?如果要收集一些新的數據點,它們很可能會更接近中間圖中的曲線。

我參加的第一場Kaggle競賽!

將原始數據集拆分為訓練集和驗證集

這說明了如何使用我們的所有數據導致過度擬合。驗證集有助於診斷此問題。驗證集上模型的得分將代表你的模型在現實世界中的表現,以及之前從未見過的數據。因此,驗證集只是數據集的一個子集,它將告訴你模型的通用化程度。

訓練模型

我們終於準備建立隨機森林了。將使用Parfit來優化我們的超參數

我參加的第一場Kaggle競賽!

最好的超參數是:

min_samples_leaf:1,

max_features:0.4,

使用隨機森林的優化參數,我們在驗證集上得到了0.1258的RMSLE。

可視化隨機森林

讓我們從隨機森林中的裝袋中看一棵決策樹(估算器,Estimator)。

我參加的第一場Kaggle競賽!

我參加的第一場Kaggle競賽!

隨機森林中的一棵決策樹

該決策樹已經可視化到深度=2。決策樹的每個節點將我們的數據分成兩半,這樣MSE的加權平均值是最好的。MSE隨著進一步下降而減少,因為樹基本上為每個節點找到了最佳分割點。

決策樹首先在TotalLivingSf的基礎上劃分數據,然後根據AgeSold和TotalLivingSf分別對其子進行劃分,依此類推。

我們在隨機森林中有300個估算器(estimators),我們採用所有這些估算器的平均值來進行預測。

特徵選擇

接下來,我們將深入研究特徵的重要性,以刪除冗餘功能,並找出哪些功能有助於深入瞭解我們的數據。

函數'rf_feat_importance'將返回一個包含列名及其各自特徵重要性的pandas數據幀。我們使用'plot_fi'函數繪製一個水平條形圖,描繪了所有列的特徵重要性。

我參加的第一場Kaggle競賽!

我參加的第一場Kaggle競賽!

特徵重要性條形圖

該圖顯示特徵的重要性以指數方式遞減,因此不需要考慮幾乎不提供數據集的洞察力的特徵。我們將刪除imp<0.005的所有特徵,然後在新數據上重新訓練我們的模型並檢查RMSLE。

我參加的第一場Kaggle競賽!

此後的RMSLE為0.12506,比之前的0.1258略有改善。特徵的數量從79減少到25。一般來說,刪除冗餘列不應該使其更糟。如果它使RMSLE變得更糟,它們畢竟不是多餘的。刪除冗餘列可能會使我們的模型更好一些。如果你考慮如何構建這些樹,當算法決定分割什麼時,需要考慮的事情就更少了。

採用更少的數據創建一棵更好的樹的可能性很小,但是它不會改變結果。這將讓我們關注最重要的特徵。

基於相關的特徵選擇

現在我們將利用Spearman秩相關係數找到特徵之間的相關性。如果兩個特徵為我們提供了相同的洞察力,那麼去掉其中的一個是明智的,因為它基本上是多餘的。這種技術有助於找到多個特徵之間的聯繫。

我們將繪製一個樹狀圖,它是一種層次聚類。從scipy.cluster導入層次結構為hc

https://en.wikipedia.org/wiki/Dendrogram

我參加的第一場Kaggle競賽!

我參加的第一場Kaggle競賽!

樹狀圖顯示所有特徵之間的相關性

兩個特徵越快碰撞,它們就越相關。基於此,我們可以看到五對彼此高度相關的特徵。

這些是:

1.)GrLivArea和TotalLivingSF。

2.)GarageArea和GarageCars。

3.)1stFlrSF和TotalBsmtSF。

4.)GarageYrBlt和YearBuilt。

5.)FireplaceQu和Fireplaces。

每對特徵中的兩個特徵都為我們提供了類似的洞察力,因此從每對特徵中刪除一個特徵是明智之舉。但是這兩者中的哪一個要被刪除呢?讓我們來看看。

現在,為了找出要刪除的兩個特徵中的哪一個(在每對特徵中),首先,我計算了一個基線分數(包括所有25個特徵),然後開始逐個刪除這10個特徵。刪除每個特徵後,我們將再次計算得分(在重新訓練模型之後)並將其與基線進行比較,以瞭解該特定特徵的移除如何影響我們的得分。

我參加的第一場Kaggle競賽!

我們的基線分數為0.12506。

現在我們將開始刪除這10個特徵並重新計算得分。

以下代碼的每個輸出在重新訓練新數據模型後告訴RMSLE。第一個令牌告訴我們刪除的功能(或列),第二個令牌在從數據中刪除該特定功能後告訴我們RMSLE。

我參加的第一場Kaggle競賽!

我們可以看到刪除了GrLivArea、TotalBsmtSF、GarageYrBlt和GarageArea,減少了我們的錯誤。因此,我們可以刪除所有這些冗餘特徵。

我參加的第一場Kaggle競賽!

在刪除所有冗餘特徵之後,我們的RMSLE從0.1258減少到0.12341。

我參加的第一場Kaggle競賽!

我們現在只剩下從79開始的21個功能。這是我們的最終模式。

我們現在應該合併訓練集和驗證集,並在這個合併的數據集上重新訓練我們的模型。

我參加的第一場Kaggle競賽!

提交預測現在我們將為測試集生成預測,但在此之前我們需要在測試集上進行類似的轉換。

我參加的第一場Kaggle競賽!

這個模型在Kaggle測試集上給出了0.12480的分數,相當於LeaderBoard中4052的排名中1338,這使我們排在前34%。

結束語

我目前正在學習第二種類型的決策樹集合,即Boosting。在本文的後面,我將介紹一個圍繞梯度增強迴歸(gradientBoostingRegressor)而不是隨機森林(Random.)的實現,並瞭解它如何影響我們的特性導入和最終得分。

我要感謝Jeremy Howard和Rachel Thomas;製作這些與眾不同的大型開放式網絡課程(MOOC)。我建議大家看看fast.ai,他們還有深度學習和計算線性代數課程以及機器學習的相關課程。

https://towardsdatascience.com/my-first-kaggle-competition-using-random-forests-to-predict-housing-prices-76efee28d42f

我參加的第一場Kaggle競賽!


分享到:


相關文章: