1. 程式人生 > >Kaggle實戰1-機器學習演算法與流程概述 + house-price example

Kaggle實戰1-機器學習演算法與流程概述 + house-price example

參考連結:https://blog.csdn.net/han_xiaoyang/article/details/50469334

 機器學習問題解決思路

上面帶著代價走馬觀花過了一遍機器學習的若干演算法,下面我們試著總結總結在拿到一個實際問題的時候,如果著手使用機器學習演算法去解決問題,其中的一些注意點以及核心思路。主要包括以下內容:

  • 拿到資料後怎麼了解資料(視覺化)
  • 選擇最貼切的機器學習演算法
  • 定位模型狀態(過/欠擬合)以及解決方法
  • 大量極的資料的特徵分析與視覺化
  • 各種損失函式(loss function)的優缺點及如何選擇
  • 問題來了,過擬合咋辦? 
    針對過擬合,有幾種辦法可以處理:

    • 增大樣本量
    • 減少特徵的量(只用我們覺得有效的特徵)
    • 增強正則化作用(比如說這裡是減小LinearSVC中的C引數) 
      正則化是我認為在不損失資訊的情況下,最有效的緩解過擬合現象的方法。
    • l2正則化,它對於最後的特徵權重的影響是,儘量打散權重到每個特徵維度上,不讓權重集中在某些維度上,出現權重特別高的特徵。
    • 而l1正則化,它對於最後的特徵權重的影響是,讓特徵獲得的權重稀疏化,也就是對結果影響不那麼大的特徵,乾脆就拿不著權重。
    特徵工程 



****************************************************************************************

label本身並不平滑。為了我們分類器的學習更加準確,我們會首先把label給“平滑化”(正態化)

這一步大部分同學會miss掉,導致自己的結果總是達不到一定標準。

這裡我們使用最有逼格的log1p, 也就是 log(x+1),避免了復值的問題。

記住喲,如果我們這裡把資料都給平滑化了,那麼最後算結果的時候,要記得把預測到的平滑資料給變回去。

按照“怎麼來的怎麼去”原則,log1p()就需要expm1(); 同理,log()就需要exp(), ... etc.

Step 3: 變數轉化

類似『特徵工程』。就是把不方便處理或者不unify的資料給統一了。

正確化變數屬性

首先,我們注意到,MSSubClass 的值其實應該是一個category,

但是Pandas是不會懂這些事兒的。使用DF的時候,這類數字符號會被預設記成數字。

這種東西就很有誤導性,我們需要把它變回成string

In [13]:
all_df['MSSubClass'].dtypes
Out[13]:
dtype('int64')
In [14]:
all_df['MSSubClass'] = all_df['MSSubClass'].astype(str)

變成str以後,做個統計,就很清楚了

In [15]:
all_df['MSSubClass'].value_counts()
Out[15]:
20     1079
60      575
50      287
120     182
30      139
70      128
160     128
80      118
90      109
190      61
85       48
75       23
45       18
180      17
40        6
150       1
Name: MSSubClass, dtype: int64

把category的變數轉變成numerical表達形式

當我們用numerical來表達categorical的時候,要注意,數字本身有大小的含義,所以亂用數字會給之後的模型學習帶來麻煩。於是我們可以用One-Hot的方法來表達category。

pandas自帶的get_dummies方法,可以幫你一鍵做到One-Hot。

In [16]:
pd.get_dummies(all_df['MSSubClass'], prefix='MSSubClass').head()
Out[16]:
  MSSubClass_120 MSSubClass_150 MSSubClass_160 MSSubClass_180 MSSubClass_190 MSSubClass_20 MSSubClass_30 MSSubClass_40 MSSubClass_45 MSSubClass_50 MSSubClass_60 MSSubClass_70 MSSubClass_75 MSSubClass_80 MSSubClass_85 MSSubClass_90
Id                                
1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0
5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0

此刻MSSubClass被我們分成了12個column,每一個代表一個category。是就是1,不是就是0。

同理,我們把所有的category資料,都給One-Hot了

處理好numerical變數

就算是numerical的變數,也還會有一些小問題。

比如,有一些資料是缺失的:

In [18]:
all_dummy_df.isnull().sum().sort_values(ascending=False).head(10)
Out[18]:
LotFrontage     486
GarageYrBlt     159
MasVnrArea       23
BsmtHalfBath      2
BsmtFullBath      2
BsmtFinSF2        1
GarageCars        1
TotalBsmtSF       1
BsmtUnfSF         1
GarageArea        1
dtype: int64

可以看到,缺失最多的column是LotFrontage

處理這些缺失的資訊,得靠好好審題。一般來說,資料集的描述裡會寫的很清楚,這些缺失都代表著什麼。當然,如果實在沒有的話,也只能靠自己的『想當然』。。

在這裡,我們用平均值來填滿這些空缺。

標準化numerical資料

這一步並不是必要,但是得看你想要用的分類器是什麼。一般來說,regression的分類器都比較傲嬌,最好是把源資料給放在一個標準分佈內。不要讓資料間的差距太大。

這裡,我們當然不需要把One-Hot的那些0/1資料給標準化。我們的目標應該是那些本來就是numerical的資料:

先來看看 哪些是numerical的:

In [22]:
numeric_cols = all_df.columns[all_df.dtypes != 'object']
numeric_cols
Out[22]:
Index(['LotFrontage', 'LotArea', 'OverallQual', 'OverallCond', 'YearBuilt',
       'YearRemodAdd', 'MasVnrArea', 'BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF',
       'TotalBsmtSF', '1stFlrSF', '2ndFlrSF', 'LowQualFinSF', 'GrLivArea',
       'BsmtFullBath', 'BsmtHalfBath', 'FullBath', 'HalfBath', 'BedroomAbvGr',
       'KitchenAbvGr', 'TotRmsAbvGrd', 'Fireplaces', 'GarageYrBlt',
       'GarageCars', 'GarageArea', 'WoodDeckSF', 'OpenPorchSF',
       'EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea', 'MiscVal',
       'MoSold', 'YrSold'],
      dtype='object')

計算標準分佈:(X-X')/s

讓我們的資料點更平滑,更便於計算。

注意:我們這裡也是可以繼續使用Log的,我只是給大家展示一下多種“使資料平滑”的辦法。