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'].dtypesOut[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_colsOut[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的,我只是給大家展示一下多種“使資料平滑”的辦法。