1. 程式人生 > >機器學習入門之決策樹(python實現)

機器學習入門之決策樹(python實現)

本次學習利用MT_Train.csv中所給的資料對MT_Test.csv中的資料進行預測,判斷客戶是否會定期存款。根據所學知識,可採用sklearn中的決策樹等方法進行程式設計。歡迎大家一起討論學習進步。

訓練集和測試集連結如下:

一. 設計思路

1.讀取訓練集和測試集檔案

2.對資料進行處理

3.訓練決策樹

4.輸出預測結果

5.將預測結果按要求儲存

 程式碼

import numpy as np
import pydotplus
from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn import ensemble
from sklearn.externals.six import StringIO
from sklearn.metrics import precision_recall_curve  
from IPython.display import Image

##read train_scv and test_scv
tmp = np.loadtxt("MT_Train.csv", dtype=np.str, delimiter=",")
tmp_test = np.loadtxt("MT_Test.csv", dtype=np.str, delimiter=",")
y_csv = np.loadtxt("MTSampleSubmission.csv", dtype=np.str, delimiter=",")
data = tmp[1:,:-1]
label = tmp[1:,-1:]
data_test = tmp_test[1:,1:]


#label_test = tmp_test[1:,-1:]
#print(data)
## binarize lable and label_test
lb = preprocessing.LabelBinarizer()
label=lb.fit_transform(label)
#label_test=lb.fit_transform(label_test)
#print(label)

## encode data and data_test
for i in range(1,10):
        data[:,i]=LabelEncoder().fit_transform(data[:,i])
        data_test[:,i]=LabelEncoder().fit_transform(data_test[:,i])
        #print(data[:,i])
data[:,14]=LabelEncoder().fit_transform(data[:,14])
data_test[:,14]=LabelEncoder().fit_transform(data_test[:,14])

## train decision tree
clf = ensemble.RandomForestClassifier(criterion='entropy',n_estimators= 60, max_depth=13, min_samples_split=110)
#print(clf)  
clf.fit(data,label)

#test and caculate precision
y_predict = clf.predict(data_test)

for i in range(0,len(y_predict)):
    if(y_predict[i]==0):
        y_csv[i+1,1] = 'no'
    else:
        y_csv[i+1,1] = 'yes'

np.savetxt('new.csv',y_csv,fmt='%s',delimiter=",")
print("finish")

二. 設計及測試過程

1. 分類器的選擇

A. 在最開始的設計中,選擇了sklearn中的DecisionTreeClassifier,分類器在之前的作業中使用過,方便簡單,用起來得心應手。但是後來發現準確率並不高,只有0.86左右,測試效果沒有那麼好,於是決定尋找新的方法,或者採用其他分類器,比如神經網路等。

B. 上網查閱資料後,發現兩個方法:隨機森林演算法和ExtraTrees的方法。sklearn.ensemble模組中包含兩種基於隨機決策樹的平均演算法:隨機森林演算法和ExtraTrees的方法。這兩種演算法都是專為決策樹設計的包含混合擾動技術的演算法。這意味著分類器依賴著引入隨機性來進行建模。整體的預測結果,來自各個獨立分類器的綜合平均預測結果。原理:隨機森林,顧名思義,就是用隨機的方式建立一個森林,森林裡面有很多的決策樹組成,隨機森林的每一棵決策樹之間是獨立沒有關聯的。

C. 由於隨機森林與決策樹的框架相同,程式碼修改起來比較簡單,只需將DecisionTreeClassifier修改為RandomForestClassifier,匯入相應的包即可。具體修改如下:


2. 引數的選擇

為了進一步提高準確率,可以對RandomForestClassifier中的引數進行設定,這個過程相當於預剪枝。可設定的引數如下:
 n_estimators: 也就是弱學習器的最代大迭次數,或者說最大的弱學習器的個數。一般來說n_estimators太小,容易欠擬合,n_estimators太大,又容易過擬合,一般選擇一個適中的數值。預設是100。

oob_score :即是否採用袋外樣本來評估模型的好壞。預設識False。個人推薦設定為True,因為袋外分數反應了一個模型擬合後的泛化能力。

criterion: CART樹做劃分時對特徵的評價標準。分類模型和迴歸模型的損失函式是不一樣的。分類RF對應的CART分類樹預設是基尼係數gini,另一個可選擇的標準是資訊增益。

RF劃分時考慮的最大特徵數max_features: 可以使用很多種型別的值,預設是"None",意味著劃分時考慮所有的特徵數;如果是"log2"意味著劃分時最多考慮log2Nlog2N個特徵;如果是"sqrt"或者"auto"意味著劃分時最多考慮N−−√N個特徵。

 決策樹最大深度max_depth: 預設可以不輸入,如果不輸入的話,決策樹在建立子樹的時候不會限制子樹的深度。一般來說,資料少或者特徵少的時候可以不管這個值。如果模型樣本量多,特徵也多的情況下,推薦限制這個最大深度,具體的取值取決於資料的分佈。常用的可以取值10-100之間。

內部節點再劃分所需最小樣本數min_samples_split: 這個值限制了子樹繼續劃分的條件,如果某節點的樣本數少於min_samples_split,則不會繼續再嘗試選擇最優特徵來進行劃分。 預設是2.如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。

葉子節點最少樣本數min_samples_leaf: 這個值限制了葉子節點最少的樣本數,如果某葉子節點數目小於樣本數,則會和兄弟節點一起被剪枝。 預設是1,可以輸入最少的樣本數的整數,或者最少樣本數佔樣本總數的百分比。如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。

葉子節點最小的樣本權重和min_weight_fraction_leaf:這個值限制了葉子節點所有樣本權重和的最小值,如果小於這個值,則會和兄弟節點一起被剪枝。 預設是0,就是不考慮權重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分佈類別偏差很大,就會引入樣本權重,這時我們就要注意這個值了。

最大葉子節點數max_leaf_nodes: 通過限制最大葉子節點數,可以防止過擬合,預設是"None”,即不限制最大的葉子節點數。如果加了限制,演算法會建立在最大葉子節點數內最優的決策樹。如果特徵不多,可以不考慮這個值,但是如果特徵分成多的話,可以加以限制,具體的值可以通過交叉驗證得到。

 節點劃分最小不純度min_impurity_split:  這個值限制了決策樹的增長,如果某節點的不純度(基於基尼係數,均方差)小於這個閾值,則該節點不再生成子節點。


三. 評價和改進

A. 優點

1. 模型易於理解、結果易於解釋;樹結構能夠視覺化

2. 訓練決策樹的成本隨著樹的高度呈指數增加。

3. 是一個白盒子模型,易於理解和解釋,不像人工神經網路模型(黑盒子),難以解釋。

4. 只需少量的資料準備。別的方法經常要求資料標準化,建立虛擬變數,移除空白值。

5. 與神經網路等分類器進行比較,訓練時間短,輸出結果比神經網路快,節省大量的時間。

B. 缺點

1. 本模型可能存在過擬合或者欠擬合的問題,但是無法直接判斷。決策樹不宜建立過度複雜的樹,以免造成過擬合。需要諸如修剪,設定葉節點所需的最小樣本數或設定樹的最大深度的機制來避免這個問題。

2. 決策樹可能不穩定,小資料的變化可能導致生成完全不同的樹。這個問題可以通過在整合模型中使用決策樹來緩解。

3. 學習一棵最優決策樹相當難的,即使對於相當簡單概念。因此,在實際的決策樹學習演算法中,往往是基於啟發式演算法(如貪婪演算法)來實現。但是貪婪演算法並不能得到全域性最優結果。這可以通過在整合模型中使用多棵樹的方法來緩解面臨的問題。

4. 在測試中發現輸出結果存在隨機性,每次輸出的結果都不一樣,後來查閱資料後發現random_state必須為已確定值,輸出才會穩定。但是多次除錯對提高準確率並無多大幫助故設為預設值。

C. 改進

1. 若需要得到穩定的輸出結果,可設定random_state

2. 可嘗試採用神經網路進行預測。