↑ " 奶糖貓 "一個值得星標的公衆號

本文約3000字,閱讀大概需要12分鐘

對於機器學習而言,如果你已經大致瞭解了相關算法的原理、理論推導,你也不是大家口中剛入門的小白了。接下來你需要將自己所學的知識利用起來,最好的方式應該就是獨立完成幾個項目實戰,項目難度入門級即可,因爲重點是幫助你瞭解一個項目的流程,比如缺失值和異常值的處理、特徵降維、變量轉換等等。

Kaggle毋庸置疑是一個很好的平臺,裏面的泰坦尼克號、房屋價格預測、手寫數字都是非常非常經典的入門實戰項目,如果你獨立完成這三個項目後感覺可以提升一下難度,就可以繼續在Playground中尋找適合自己的項目。但如果你感覺還需要幾個簡單的項目鞏固一下,這裏給大家安利一下 SofaSofa競賽平臺

專業程度雖然不及Kaggle,但練習賽中十個簡單項目用來練手還是不錯的,種類也是非常全的,包括分類、迴歸預測、自然語言處理、圖像識別等等,本文在練習賽【8】——地震後建築修復建議的基礎上實現。

瞭解數據集

首先一定要做的是瞭解數據集,因爲大多數據集的特徵名都是以英文或者以英文簡寫搭配命名,只有真正瞭解一個特徵的意義,才能更好地分析該特徵與標籤變量之前存在的關係。SofaSofa在每個競賽中都會有一個表格,給出所有變量對應的解釋。

可以看到這個數據集的特徵並不是很多,但訓練集共有65萬個樣本,我們都知道數據多對於建模是有好處的,因爲數據越多覆蓋面就越廣,會提高模型的準確率,當然這可能會犧牲一些內存和計算時間。標籤變量y,共有四種可能取值,說明這是一個多元分類問題。

沒有缺失值是不錯的消息,除標籤變量y之外,共有9個數值型比變量和5個類別型變量。

可視化分析

可視化分析一方面是幫助我們找出樣本中的異常點和離羣點,一方面也是幫助分析特徵與標籤變量之間的關係。但上面提及了這個訓練集足足有65萬條數據,如果同時利用所有樣本繪製圖像,圖像可能會被樣本點填滿,很難從中得出有用的信息。

所以這裏可以選擇隨機抽樣的方式,每次抽取1000-2000個樣本繪製圖像進行分析,可以多抽取幾次,防止數據的偶然性。這裏選擇用散點圖可視化數值型特徵,用area和age爲例。

area特徵中有一些數值偏大,但不能說其是異常點,因爲一些大型建築物佔地面積3000不是不可能的,但2000個樣本,僅有不到20個樣本的佔地面積大於1500,所以可以將其視爲離羣點,離羣點在建模時是會影響擬合的,所以選擇捨去。

對於建築物的年限age而言,可視化後會發現有很多樣本在age這一特徵的數值都爲999,中間卻有很大的空缺,比如沒有一個樣本點的age位於500-900之間,所以這類樣本被視爲異常點,再結合離羣點分析,可以選擇一個閾值進行過濾。其他數值型特徵可以做同樣的操作,這裏不再過多介紹。

這個數據集還有個奇怪的地方就是有很多樣本地震後的樓層、高度都要高於地震發生之前,這顯然是不可能發生的,可能是在數據填充時出現了錯誤,利用布爾索引過濾掉此類特徵。

#布爾索引

data1 = data1[data1[ 'floors_before' ]>=data1[ 'floors_after' ]]

data1 = data1[data1[ 'height_before' ]>=data1[ 'height_after' ]]

data1.reset_index(drop =  True

)

#重置索引

然後利用相關矩陣對所有的數值型特徵進行一下相關性分析,通過觀察相關性捨去一些沒有必要的特徵達到降維的目的。

這裏"district_id"和"area_id"是完全相關的,可以隨便留下一個,或者都刪去,因爲相關性確實小的可憐;可以看到這裏增加了兩個新的變量"floors_diff"和"height_diff",就是地震前後的建築物層數和高度的差值,可以觀察一下標籤變量"y"和這六個屬性的相關性,與地震前的信息相關性極低,也就是說,標籤變量很少關注一個建築物震前的信息,而是着重關注經過地震之後建築發生變化的信息。

類別型變量轉換

類別型變量不方便後期建模時傳入數據,所以我們需要提前將類別型變量轉換爲算法能識別的數值型,變量轉換方式有很多種,比如有序變量、啞變量、虛擬變量。

對於"position"這一特徵,可以進行有序變量,由於僅有一個特徵,所以沒有調用sklearn中的API,而是直接利用自定義函數結合apply函數進行轉換。

def pos (e) :

if e ==  "Not attached" :

return 0

elif e ==  "Attached-1 side" :

return 1

elif e== "Attached-2 side" :

return 2

else :

return 3

data1[ 'position'

] = data1[

'position'

].apply(pos)

而剩下的幾個類別型變量皆爲無序變量,可以將其轉化爲啞變量,再進一步轉化爲虛擬變量。相比於sklearn中的API,pandas自帶的方法看起來更加簡潔。

#啞變量編碼

dummy_df = pd.get_dummies(data1.iloc[:, 6

:

10

])

如果你感覺這種方式簡單,並沒有懂啞變量編碼的意思和過程,可以試着瞭解一下下面這個函數,同樣是實現啞變量編碼。

def dummy_code (var) :

#獲取特徵中所有變量

var_unique = var.unique()

#新建一個DataFrame

dummy = pd.DataFrame()

for val  in var_unique:

#利用一個布爾型數組存儲編碼後的變量

bo = (val==var)

#命名,並將True轉爲1,False轉爲0

dummy[var.name+ "_" +str(val)] = bo.astype(int)

return

dummy

將啞變量進一步轉化爲虛擬變量合併至數據集中,代碼如下:

#每個特徵刪去一個類別,得到虛擬變量

dummy_df1 = dummy_df.drop([ 'land_condition_S' , 'foundation_type_O' , 'roof_type_H' , 'ground_floor_type_T' ],axis =  1 )

#刪去原特徵,合併虛擬變量

data1 = data1.drop([ 'land_condition' , 'foundation_type' , 'roof_type' , 'ground_floor_type' ],axis =  1 )

data1 = pd.concat([data1,dummy_df1],axis = 

1

)

可能很多夥伴不太瞭解爲什麼虛擬變量可以這樣轉換,虛擬變量與啞變量相比,減少了特徵的維度,本質是類似的,以"roof_type"這一特徵舉例,經過啞變量轉換形成三個新特徵:["roof_type_H","roof_type_L","roof_type_R"],如果在"roof_type"爲"R"的樣本,在啞變量的表達方式應該是[0,0,1],但是如果從啞變量中刪去"roof_type_R"這一特徵,表達方式就可以變成[0,0],通過唯一性就可以利用前兩個特徵推出第三個特徵的值,所以減少了不必要的特徵以實現降維。

當然這裏還可以做一下方差過濾、相關性分析等操作進一步實現特徵降維,各位在實操的時候可以自己試一下。

建模工作

前面說過了這個是一個多元分類項目,所以在建模的時候可以有兩種選擇,一是利用多元分類器,比如隨機森林、樸素貝葉斯,二就是利用二元分類器實現多元分類任務,比如邏輯迴歸、SVM。

後面文章會寫一篇關於二元分類器實現多元分類的文章,本文就集中於多元分類器的實現,主要用到的兩個分類器是隨機森林和LGBM。

一般建模的流程大致是在訓練集上切分訓練集和測試集,有的數據需要標準化處理,然後訓練模型,利用測試集進行預測,獲取模型的準確率或其他衡量模型好壞的指標,下面以隨機森林分類器模擬一下該流程。

首先進行數據切分,可以選擇控制訓練集和測試集的比例:

from sklearn.model_selection  import train_test_split

features = data2.iloc[:, 0 : -1 ].values

label = data2.iloc[:, -1 ].values

X_train,X_test,y_train,y_test = train_test_split(features,label,test_size = 

0.3

)

這裏介紹一下可以減少代碼量的管道流,如果正常來說,我們可能要分別實例化標準化和PCA的API,然後再傳入訓練 和測試集,這些操作可以利用管道流封裝到一起,讓代碼看起來更加簡潔。

from sklearn.ensemble  import RandomForestClassifier

from sklearn.decomposition  import PCA

from sklearn.pipeline  import make_pipeline,Pipeline

#管道流簡化工作流

pipe_rf = make_pipeline(StandardScaler(),

PCA(n_components= 10 ),

RandomForestClassifier())

pipe_rf.fit(X_train,y_train)

#得到每個類別的概率

pred_y_rf = pipe_rf.predict_prob(X_test)

利用predict_prob計算出標籤變量得到每個類別的概率,然後利用索引排序可以得到概率最大的兩個類別:

pred_df = pd.DataFrame(data=pred_y_rf.argsort()[:,  -2 :][:, :: -1 ], columns=[ 'y1''y2' ])

pred_df.to_csv( "eq_submission.csv"

,index=

False

)

由於數據量比較大,調參比較費時,在沒有調參的情況下,隨機森林模型的概率大致爲68%,LGBM模型的準確率大致爲70%,準確率並不是太好,除準確率外還可以通過查全率、查準率、F1-score衡量一下模型的好壞,上文大體上提供了一個建模前及建模的思路而已,夥伴們可以利用自己的思路,再加上調參應該會得到一個不錯的模型。

這幅圖是關於特徵重要度的餅圖,可以根據餅圖再調節特徵,其中area佔比是比最大的,然後"distict_id"佔比也是不小的,但是上文關係矩陣中與標籤變量的相關性又很小,所以分析要相互結合、更加全面一些纔好。

說在最後

上面的一系列操作都是爲了最後的模型,但如果作爲一個競賽,你需要提交一份文件,而這份文件從何來?競賽會給出一個不含標籤變量的測試集!注意與測試集中分割出的測試集不同。我們同樣需要對測試集做一些數據處理,操作和訓練集類似,然後將訓練出的模型應用在測試集上,會得出最後的結果保存成一個新的csv文件,這就是你最後需要提交的文件啦。

後臺回覆關鍵字“地震”可獲取源碼供參考

Read More

Kaggle競賽入門實戰——機器學習預測房屋價格

20年前的幾行代碼竟如此牛逼?驚了

一文湊齊四種變量轉換方法!

End

奶糖貓   

優秀的人都在看   

在看點一下

相關文章