工具
評估函數:RMSE即損失函數,範數越大,越注重預測值偏差大的樣例學習
用 python 的pandas包導入樣本數據,查看前五行,每一行表示一個街區,包含十項數據特徵:測試
經度 | 維度 | 房齡 | 房間數 | 臥室數 | 人口數 | 家庭數 | 收入 | 房價 | 臨海 |
---|---|---|---|---|---|---|---|---|---|
-122.23 | 37.88 | 41 | 880 | 129 | 322 | 126 | 8.3252 | 452600 | NEAR BAY |
-122.22 | 37.86 | 21 | 7099 | 1106 | 2401 | 1138 | 8.3014 | 358500 | NEAR BAY |
-122.24 | 37.85 | 52 | 1467 | 190 | 496 | 177 | 7.2574 | 352100 | NEAR BAY |
-122.25 | 37.85 | 52 | 1274 | 235 | 558 | 219 | 5.6431 | 341300 | NEAR BAY |
-122.25 | 37.85 | 52 | 1627 | 280 | 565 | 259 | 3.8462 | 342200 | NEAR BAY |
其中房價一列實際是這次任務的 label, 查看數據基本狀況:編碼
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
longitude 20640 non-null float64
latitude 20640 non-null float64
housing_median_age 20640 non-null float64
total_rooms 20640 non-null float64
total_bedrooms 20433 non-null float64
population 20640 non-null float64
households 20640 non-null float64
median_income 20640 non-null float64
median_house_value 20640 non-null float64
ocean_proximity 20640 non-null object
dtypes: float64(9), object(1)
能夠看到一共有 20640 行記錄,注意到其中 total_rooms 屬性有207行缺失,ocean_proximity 屬性是 object 類型,查看該屬性的統計狀況:
<1H OCEAN 9136
INLAND 6551
NEAR OCEAN 2658
NEAR BAY 2290
ISLAND 5
對9項數值型屬性畫直方圖,感覺下每一個屬性的分佈狀況:
能夠看到 housing_median_age、median_house_value、median_income 有明顯的翹尾狀況,說明這三個屬性在數據收集階段,作過被截斷處理。median_house_value 做爲這次任務的預測目標值,它的截斷處理在實際狀況中多是個問題,由於它意味着你模型的預測值可能沒法超過這個上限。上圖還能夠看出有四項屬性屬於「長尾分佈」的狀況,通常來講,機器學習的模型更喜歡相似正態分佈的「鍾型」特徵。
人腦很是擅長圖像視覺的信息處理。用經度緯度肯定地理位置,用圓圈大小表示人口數量,用熱力圖表示房價高低,再從外部導入一張經緯度吻合的地圖,能夠獲得一張可視化的數據圖:
能夠看到海景房房價廣泛偏高,可是北部區域是個例外,說明臨海距離應該是個很好的特徵。另外,人口彙集地中心區域,房價也相應偏高,是否是作聚類以後,計算到聚類中心的距離也是一個很好的特徵呢?
相關性既包括特徵與label的相關性,也包括特徵之間的相關性。首先看特徵與 label 之間的皮爾遜係數:
median_income 0.687160
total_rooms 0.135097
housing_median_age 0.114110
households 0.064506
total_bedrooms 0.047689
population -0.026920
longitude -0.047432
latitude -0.142724
觀察房價與收入的二維圖:
整體上,房價與收入具備很強的相關性,收入越高,該地區的房價也越高。可是也有一些收入較高,可是房價很低,或者收入較低,房價奇高的點,多是異常點,須要從訓練數據中去除。
測試集從數據集中分離而來,大小通常設置爲所有數據的20%。分離的辦法能夠隨機取,有點是採樣均勻,缺點是每次取出的測試集可能不同。要克服這個缺點,在隨機取的時候,能夠固定隨機數種子。其餘的方法還有根據某列屬性的尾號或者 md5 來劃分,優勢是每次運行的測試集是固定的,肯定是要確保尾號或者 md5 數值是均勻分佈的,而且與 label 不存在相關性。在工業界,上線算法ab分桶時,經常也用相似的方法,好比按照用戶id尾號分流、按照用戶id的md5分流等,特別要注意未登陸用戶的分桶狀況,由於未登陸用戶與點擊率是有相關性的。
隨機產生測試集,可能有的一個弊端是,重要屬性的部分區間可能丟失。舉個極端的例子,在全部分類模型中,label是最重要的屬性,假設100個樣本中只有2個正樣本,則有很大機率訓練樣本所有是負樣本。這個任務中,median_income 屬性是決定房價的一個重要特徵,在直方圖中,能夠看到收入大於7.5的樣本已經比較稀疏了。若是徹底按照隨機採樣方法產生訓練樣本和測試樣本,有可能訓練樣本中徹底不包含收入大於7.5的樣本,這對於模型訓練是很不利的。
解決的方法很簡單,將 median_income 進行分組,每組裏面按照0.2的比例抽取測試樣本。分組的時候,注意每組裏面樣本數量不能太少,能夠參考以下處理方法:
group = ceil(min(median\_income,7.5) / 1.5)
將 median_income 分爲5組,每組按比例採樣,這樣處理的結果是,測試樣本在 median_income 的分佈,比當作總體(一組)徹底隨機採樣的方法,更符合總體分佈。
先用線性迴歸模型在訓練集上訓練,而後用訓練好的模型再次預測訓練集的label,計算RMSE爲6.8w刀,MAE偏差爲4.9w刀,模型明顯underfitting。解決的方法有:用複雜模型、用更好的特徵、用更弱的約束。
改用決策樹模型進行訓練,獲得訓練集的偏差爲0.0,在測試集中偏差極大 。在迴歸問題裏,百分百徹底預測準確基本是不可能的,說明模型存在過擬合現象。解決的方法有:用簡單模型、用更大的數據量、更強的約束、ensemble方法等。爲了更好評估過擬合狀況,能夠用 K-fold 進行交叉驗證。基本過程以下:把所有數據集隨機分紅K份,每次挑選其中K-1份訓練數據,剩下一份做爲測試集計算偏差,總共重複K次。相比於只劃分一份訓練集和測試集,這種方法更加健壯。
隨機森林模型是多個決策樹模型ensemble後的結果,比單個決策樹模型具備更強抗overfitting的能力。改用隨機森林模型進行訓練,發現結果好得多,可是測試集偏差依舊遠遠大於訓練集偏差,說明模型還須要更強的約束。爲了找到較好的約束參數,能夠採用grid search方法。
模型的超參可能有多個,每一個有多種選擇,由此造成了參數網格grid。前面講過用交叉驗證的方法能夠評估一個模型的效果,以上兩種方法結合,可讓模型遍歷每一個網格點,用交叉驗證的方法獲得該網格點的模型預測偏差,從而找到表現最好的模型。最終找的的較好超參是 max_features 爲6,n_estimators 爲 30, RMSE 49900。
準確率top4%的 kenerl 地址連接,真實的數據集和本文以上描述有所區別