決策樹和隨機森林模型筆記


一、決策樹

1 算法思想

經典的十大數據挖掘算法1之一,是一種類似於流程圖的樹結構,其規則就是IF…THEN…的思想
可以用於數值型因變量的預測和離散型因變量的分類2

2 算法特點

  • 算法簡單直觀、通俗易懂
  • 算法的結果輸出具有很強的解釋性

3 節點字段的選擇

3.1 信息增益

  • 思想:在根節點或中間節點的變量選擇過程中,就是挑選出各自變量下因變量的信息增益最大的。信息增益計算公式:
    GainA(D)=H(D)H(DA)Gain_A(D)=H(D)-H(D|A)
  • 指標缺點:信息增益會偏向於取值較多的字段。

3.2 信息增益率

  • 思想:在信息增益的基礎上進行相應的懲罰。信息增益率的公式可以表示爲:
    GainRatioA(D)=GainA(D)HAGain-Ratio_A(D) = \frac{Gain_A(D)}{H_A}
  • 如果用於分類的數據集中各離散型自變量的取值個數沒有太大差異,那麼信息增益指標與信息增益率指標在選擇變量過程中並沒有太大的差異

3.3 基尼指數

基尼指數的計算公式:
Gini(D)=k=1KCkD(1CkD)=1k=1K(CkD)2Gini(D)=\sum_{k=1}^K\frac{|C_k|}{|D|} (1-\frac{|C_k|}{|D|})=1-\sum_{k=1}^K(\frac{|C_k|}{|D|})^2
其中,|D|表示事件中的所有樣本點,|Ck|表示事件的第k個可能值出現的次數.

4 決策樹方法

  • 決策樹中的ID3算法使用 信息增益 指標實現根節點或中間節點的字段選擇。
  • 決策樹中的C4.5算法 使用信息增益率指標實現根節點或中間節點的字段選擇。
  • 決策樹中的CART算法使用的字段選擇指標是基尼指數,並且能夠讓決策樹預測連續型的因變量

方法異同

  • C4.5算法ID3算法,都只能針對離散型因變量進行分類
  • CART算法既可以對離散型因變量進行處理,也可以預測連續型的因變量
  • ID3和C4.5都屬於多分支的決策樹,CART則是二分支的決策樹

不管是ID3、C4.5還是CART決策樹,在建模過程中都可能存在過擬合的情況,即模型在訓練集上有很高的預測精度,但是在測試集上效果卻不夠理想。
決策樹 不對多重共線性敏感,故無須刪除某類啞變量中的一個。

5 剪枝技術

決策樹的剪枝通常有兩類方法:

  • 一類是預剪枝:指在樹的生長過程中就對其進行必要的剪枝。
  • 另一類是後剪枝:指決策樹在得到充分生長的前提下再對其返工修剪。

5.1 預剪枝

預剪枝對應的主要技術有:

  • 限制樹生長的最大深度,即決策樹的層數
  • 限制決策樹中間節點數
  • 限制葉節點中所包含的最小樣本量
  • 限制決策樹生成的最多葉節點數量等

5.2 後剪枝

後剪紙對應的常用技術有:

  • 誤差降低剪枝法
  • 悲觀剪枝法
  • 代價複雜度剪枝法等

5.2.1 誤差降低剪枝法

思想:該方法屬於一種自底向上的後剪枝方法,剪枝過程中需要結合測試數據集對決策樹進行驗證,如果某個節點的子孫節點都被剪去後,新的決策樹在測試數據集上的誤差反而降低了,則表明這個剪枝過程是正確的,否則就不能對其剪枝。

缺點:需要結合測試數據集才能夠實現剪枝,因此就可能導致剪枝過度的情況。

5.2.2 悲觀剪枝法

該方法的剪枝過程恰好與誤差降低剪枝法相反,它是自頂向下的剪枝過程。對比剪枝前後葉節點誤判率的標準就是,如果剪枝後葉節點的誤判率期望在剪枝前葉節點誤判率期望的一個標準差內,則認爲剪枝是合理的,否則不能剪枝。

5.2.3 代價複雜度剪枝法

一種基於目標函數的剪枝方法。該剪枝方法涉及兩則信息,一則是代價,是指將中間節點替換爲葉節點後誤判率會上升;另一則是複雜度,是指剪枝後葉節點的個數減少,進而使模型的複雜度下降。

二、隨機森林

1 算法思想

算法的核心思想就是採用多棵決策樹的投票機制,完成分類或預測問題的解決。

  • 對於分類問題,將多棵樹的判斷結果用作投票,根據少數服從多數的原則,最終確定樣本所屬的類型;
  • 對於預測性問題,將多棵樹的迴歸結果進行平均,最終用於樣本的預測值。

隨機森林的隨機性體現在兩個方面:

  • 一是每棵樹的訓練樣本是隨機的
  • 二是樹中每個節點的分裂字段也是隨機選擇的

2 算法特點

  • 運行速度快
  • 預測準確率高
  • 隨機森林不容易陷入過擬合(隨機性的引入)

三、繪製決策樹圖

在繪製決策樹圖之前,確保電腦中安裝了Graphviz工具。讀者可以前往 https://graphviz.gitlab.io/_pages/Download/Download_windows.html 下載,然後將解壓文件中的bin路徑設置到環境變量中,重新啓動Python即可.

四、決策樹實例

對Titanic數據集進行擬合,該數據集一共包含891個觀測和12個變量,其中變量Survived爲因變量,1表示存活,0表示未存活。

1 數據預處理

缺失值類別變量進行簡單處理。

# 導入第三方模塊
import pandas as pd
# 讀入數據
Titanic = pd.read_csv(r'Titanic.csv')
# print('數據前3行示例:\n',Titanic.head(3))

# 刪除無意義的變量,並檢查剩餘自字是否含有缺失值
Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace = True)
print('數據的缺失情況:\n',Titanic.isnull().sum(axis = 0))

# 對Sex分組,用各組乘客的平均年齡填充各組中的缺失年齡
fillna_Titanic = pd.DataFrame()
for i in Titanic.Sex.unique():
    update =  Titanic.loc[Titanic.Sex == i,:].fillna(value = {'Age': Titanic.Age[Titanic.Sex == i].mean()})  
    fillna_Titanic = pd.concat([fillna_Titanic,update])
    
Titanic = fillna_Titanic
# 使用Embarked變量的衆數填充缺失值
Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=True)


# 將數值型的Pclass轉換爲類別型,否則無法對其啞變量處理
Titanic.Pclass = Titanic.Pclass.astype('category')
# 啞變量處理
dummy = pd.get_dummies(Titanic[['Sex','Embarked','Pclass']])
# 水平合併Titanic數據集和啞變量的數據集
Titanic = pd.concat([Titanic,dummy], axis = 1)
# 刪除原始的Sex、Embarked和Pclass變量
Titanic.drop(['Sex','Embarked','Pclass'], inplace=True, axis = 1)

2 決策樹模型

# ------------ 構建決策樹模型----------------------------
# 導入第三方包
from sklearn import model_selection
# 取出所有自變量名稱
predictors = Titanic.columns[1:]
# 將數據集拆分爲訓練集和測試集,且測試集的比例爲25%
X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived, 
                                                                    test_size = 0.25, random_state = 1)

# 網格搜索法 尋找最優參數組合
# 導入第三方模塊
from sklearn.model_selection import GridSearchCV
from sklearn import tree

# 預設各參數的不同選項值
max_depth = [2,3,4,5,6]
min_samples_split = [2,4,6,8]
min_samples_leaf = [2,4,8,10,12]
# 將各參數值以字典形式組織起來
parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf}
# 網格搜索法,測試不同的參數值
grid_dtcateg = GridSearchCV(estimator = tree.DecisionTreeClassifier(), param_grid = parameters, cv=10)
# 模型擬合
grid_dtcateg.fit(X_train, y_train)
# 返回最佳組合的參數值
print('最佳組合的參數值:\n',grid_dtcateg.best_params_)

# 導入第三方模塊
from sklearn import metrics
# 構建分類決策樹
CART_Class = tree.DecisionTreeClassifier(max_depth=grid_dtcateg.best_params_['max_depth'],
                                         min_samples_leaf = grid_dtcateg.best_params_['min_samples_leaf'],
                                         min_samples_split=grid_dtcateg.best_params_['min_samples_split'])
# 模型擬合
decision_tree = CART_Class.fit(X_train, y_train)
# 模型在測試集上的預測
pred = CART_Class.predict(X_test)
# 模型的準確率
print('模型在測試集的預測準確率:\n',metrics.accuracy_score(y_test, pred))

最佳組合的參數值: {‘max_depth’: 6, ‘min_samples_leaf’: 4, ‘min_samples_split’: 4}
模型在測試集的預測準確率: 0.8116591928251121

3 繪製ROC曲線

# 繪製ROC曲線
# 導入第三方包
import matplotlib.pyplot as plt
y_score = CART_Class.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 計算AUC的值
roc_auc = metrics.auc(fpr,tpr)

# 繪製面積圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加邊際線
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加對角線
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x軸與y軸標籤
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 顯示圖形
# plt.show()

在這裏插入圖片描述

4 繪製決策樹圖

# 導入第三方模塊
from sklearn.tree import export_graphviz
from IPython.display import Image
import pydotplus
from sklearn.externals.six import StringIO
# 繪製決策樹
dot_data = StringIO()
export_graphviz(
    decision_tree,
    out_file=dot_data,  
    feature_names=predictors,
    class_names=['Unsurvived','Survived'],  
    # filled=True,
    rounded=True,  
    special_characters=True
)
# 決策樹展現
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
Image(graph.create_png()) 

在這裏插入圖片描述

五、隨機森林實例

同第四部分決策樹實例數據,在上例數據處理後的基礎上,構建隨機森林實例。

1 隨機森林模型

# --------- 構建隨機森林 --------------------
from sklearn import ensemble\

RF_class = ensemble.RandomForestClassifier(n_estimators=200, random_state=1234)
# 隨機森林的擬合
RF_class.fit(X_train, y_train)
# 模型在測試集上的預測
RFclass_pred = RF_class.predict(X_test)
# 模型的準確率
print('模型在測試集的預測準確率:\n',metrics.accuracy_score(y_test, RFclass_pred))

模型在測試集的預測準確率: 0.852017937219731

2 繪製ROC曲線

# 繪製ROC曲線
y_score = RF_class.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 繪圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

在這裏插入圖片描述

3 變量的重要程度

# 變量的重要性程度值
importance = RF_class.feature_importances_
# 構建含序列用於繪圖
Impt_Series = pd.Series(importance, index = X_train.columns)
# 對序列排序繪圖
Impt_Series.sort_values(ascending = True).plot('barh')
plt.show()

在這裏插入圖片描述


  1. 參考博文:https://blog.csdn.net/qq_36523839/article/details/82383597 ↩︎

  2. 從零開始學Python數據分析與挖掘/劉順祥著.—北京:清華大學出版社,2018ISBN 978-7-302-50987-5 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章