一.算法原理
? 決策樹(decision tree)是一種基本的分類與回歸方法
? 決策樹由結(jié)點(node)和有向邊(directed edge)組成
? 結(jié)點類型:根結(jié)點(root node),內(nèi)部結(jié)點(internal node)和葉結(jié)點(leaf node)
使用決策樹做預(yù)測時,每一步驟都很重要,數(shù)據(jù)收集不到位,將會導(dǎo)
致沒有足夠的特征讓我們構(gòu)建錯誤率低的決策樹;另外數(shù)據(jù)特征充足,但是不知道用哪些特征好,將會導(dǎo)致無法構(gòu)建出分類效果好的決策樹模型。
從算法方面看,決策樹的構(gòu)建非常重要,決策樹的構(gòu)建需要注意:
? 特征選擇
? 決策樹的生成
? 決策樹的修剪
特征選擇在于選取對訓(xùn)練數(shù)據(jù)具有分類能力的特征,特征選擇的標(biāo)準(zhǔn)是信息增益(information gain);
信息的度量方式稱為香農(nóng)熵或者簡稱為熵(entropy)。熵定義為信息量的期望值。在信息論與概率統(tǒng)計中,熵是表示隨機變量不確定性的度量。
決策樹構(gòu)建:
? 第一次劃分之后,數(shù)據(jù)集被向下傳遞到樹的分支的下一個結(jié)點。在這個結(jié)點上,我們可以再次劃分?jǐn)?shù)據(jù)。因此我們可以采用遞歸的原則處理數(shù)據(jù)集。
? 構(gòu)建決策樹的方法:ID3、C4.5和CART。
二.決策樹分類方法
2.1 ID3
? ID3算法(Iterative Dichotomiser 3):
? ID3算法的核心是在決策樹各個結(jié)點上對應(yīng)信息增益最大準(zhǔn)則選擇特征,遞歸地構(gòu)建決策樹;
? 具體流程:從根結(jié)點開始,對結(jié)點計算所有可能的特征的信息增益,選擇信息增益最大的特征作為結(jié)點的特征,由該特征的不同取值建立子節(jié)點;再對子結(jié)點遞歸地調(diào)用以上方法,構(gòu)建決策樹。ID3相當(dāng)于用最大似然法進行概率模型的選擇。
剪枝分為預(yù)剪枝和后剪枝:
? 預(yù)剪枝:就是在構(gòu)建決策樹的時候提前停止。比如指定樹的深度最大為3,那么訓(xùn)練出來決策樹的高度就是3,預(yù)剪枝主要是建立某些規(guī)則限制決策樹的生長,降低了過擬合的風(fēng)險,降低了建樹的時間,但是有可能帶來欠擬合問題。
? 后剪枝:后剪枝是一種全局的優(yōu)化方法,在決策樹構(gòu)建好之后,然后才開始進行剪枝。后剪枝的過程就是刪除一些子樹,這個葉子節(jié)點的標(biāo)識類別通過大多數(shù)原則來確定,即屬于這個葉子節(jié)點下大多數(shù)樣本所屬的類別就是該葉子節(jié)點的標(biāo)識。選擇減掉哪些子樹時,可以計算沒有減掉子樹之前的誤差和減掉子樹之后的誤差,如果相差不大,可以將子樹減掉。一般使用后剪枝得到的結(jié)果比較好。
2.2 C4.5
? C4.5決策樹:
? 通過信息增益率選擇分裂屬性,克服了ID3算法中通過信息增益傾向于選擇擁有多個屬性值的屬性作為分裂屬性的不足。
? 能夠處理離散型和連續(xù)型的屬性類型,即將連續(xù)型的屬性進行離散化處理
? 能夠處理具有缺失屬性值的訓(xùn)練數(shù)據(jù)。
? 連續(xù)型屬性的離散化處理 :
? 當(dāng)屬性類型為連續(xù)型,需要對數(shù)據(jù)進行離散化處理。C4.5算法針對連續(xù)屬性的離散化處理的核心思想:將屬性A的N個屬性值按照升序排列;通過二分法將屬性A的所有屬性值分成兩部分(共有N-1種劃分方法,二分的閾值為相鄰兩個屬性值的中間值);計算每種劃分方法對應(yīng)的信息增益,選取信息增益最大的劃分方法的閾值作為屬性A二分的閾值。
2.3 CART
? CART(Classification And Regression Trees):
? CART分類回歸樹是一種典型的二叉決策樹,可以做分類或者回歸。如果待預(yù)測結(jié)果是離散型數(shù)據(jù),則CART生成分類決策樹;如果待預(yù)測結(jié)果是連續(xù)型數(shù)據(jù),則CART生成回歸決策樹。
? 作為分類決策樹時,待預(yù)測樣本落至某一葉子節(jié)點,則輸出該葉子節(jié)點中所有樣本所屬類別最多的那一類;作為回歸決策樹時,待預(yù)測樣本落至某一葉子節(jié)點,則輸出該葉子節(jié)點中所有樣本的均值。
? CART用作分類樹時采用基尼系數(shù)最小化原則,用作回歸樹時用平方誤差最小化作為選擇特征的準(zhǔn)則,遞歸地生成二叉樹。
? 基尼系數(shù):
? 創(chuàng)建分類樹遞歸過程中,CART每次都選擇當(dāng)前數(shù)據(jù)集中具有最小Gini系數(shù)的特征作為結(jié)點劃分決策樹。
三.決策樹案例
3.1 鳶尾花
sklearn上面的數(shù)據(jù)與案例;
from sklearn.datasets import load_iris
from sklearn import tree
import graphviz
import os
#引入數(shù)據(jù)
iris=load_iris()
X=iris.data
y=iris.target
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X,y)
#引入graphviz模塊用來導(dǎo)出圖,結(jié)果圖如下所示
dot_data=tree.export_graphviz(clf,out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True,rounded=True,
special_characters=True)
os.chdir(r'D:\graphviz-2.38\graphviz-2.38\release\bin')
graph=graphviz.Source(dot_data)
graph.view()
但是這樣畫出來的圖不能顯示中文,需要處理下,顯示中文需要安裝包graphviz,sklearn上提供了該安裝包的下載地址,注意下載的包到2.3即可,太新的安裝包不能解決中文問題(親測)。
需要記住安裝包安裝的位置。
os.chdir(r'D:\graphviz-2.38\release\bin')
iris=load_iris()
X=iris.data
y=iris.target
clf=tree.DecisionTreeClassifier()
clf=clf.fit(X,y)
with open("tree.dot",'w',encoding="utf-8") as f:
f = tree.export_graphviz(clf,out_file=f,
feature_names=['花萼長度','花萼寬度','花瓣長度','花瓣寬度'],
class_names=iris.target_names,
filled=True,rounded=True,special_characters=True)
改過程的原理就是,將模型傳入到export_graphviz,生成一個中間文檔tree.dot,這個中間文檔在D:\graphviz-2.38\release\bin里面,用notepad打開tree.dot,將前兩行(兩處)fontname,改成fontname="Microsoft YaHei"。

接下來,打開power shell的promot,cd命令行打開D:\graphviz-2.38\release\bin,輸出 dot -Tpng tree.dot -o test.png , 將結(jié)果保存為圖片。

3.2 波斯頓預(yù)測房價
from sklearn.datasets import load_boston
import graphviz
import numpy as np
from sklearn import tree
boston = load_boston()
X = boston.data
y = boston.target
from sklearn.model_selection import train_test_split
data_train, data_test, target_train, target_test =train_test_split(X, y, test_size = 0.2, random_state = 42)
#送入模型
dir = tree.DecisionTreeRegressor()
dir.fit(data_train,target_train)
dir.score(data_test,target_test)
進行參數(shù)調(diào)優(yōu)
from sklearn.model_selection import GridSearchCV
# 加載調(diào)優(yōu)函數(shù)
# 設(shè)置參數(shù)可取值
gini_impure = np.linspace(0,0.01,10)
param_grid = {"min_impurity_decrease":gini_impure,"max_depth":range(2,10),"min_samples_split":range(2,50,2)}
# 設(shè)置參數(shù)網(wǎng)格
reg = GridSearchCV(tree.DecisionTreeRegressor(),param_grid=param_grid,cv=10)
# 建模
reg.fit(data_train,target_train)
找出最優(yōu)參數(shù)

、
將最優(yōu)參數(shù)送入模型
reg = tree.DecisionTreeRegressor(min_impurity_decrease=0,max_depth=9,min_samples_split=28)
# 加載模型
reg.fit(data_train,target_train)
reg.score(data_test,target_test)
引入graphviz模塊用來導(dǎo)出圖,結(jié)果圖如下所示
import os
dot_data_a=tree.export_graphviz(reg,out_file=None,
feature_names=boston.feature_names,
filled=True,rounded=True,
special_characters=True)
os.chdir(r'D:\graphviz-2.38\graphviz-2.38\release\bin')
graph=graphviz.Source(dot_data_a)
graph.view()

3.3 將業(yè)務(wù)數(shù)據(jù)用于決策樹模型
數(shù)據(jù)預(yù)覽:本次業(yè)務(wù)數(shù)據(jù)為健康度數(shù)據(jù),描述的是各個區(qū)域六個特征指標(biāo),會影響該區(qū)域的最終評分等級(A>B>C>D>E)等級。數(shù)據(jù)如下。

數(shù)據(jù)建模,將特征值與標(biāo)簽處理好。
import pandas as pd
import graphviz
import glob
import os
df_B = pd.read_excel("./測算表-8.31-發(fā)布版.xlsx",sheet_name='B匯總')
df_B = df_B[['環(huán)滬指數(shù)指標(biāo)', '帶看滲透率指標(biāo)', 'VR指標(biāo)', '分享指標(biāo)', '市內(nèi)破指標(biāo)',
'環(huán)滬破指標(biāo)','等級']]
##特征與標(biāo)簽
df_B_X = df_B.iloc[:,:-1]
df_B_y = df_B.iloc[:,[-1]]
df_B_y_label = df_B_y.replace({'A': 'A~B', 'B':'A~B', 'C':'C', 'D':'D~E', 'E':'D~E'})
送入決策樹模型
from sklearn import tree
clf=tree.DecisionTreeClassifier(max_depth=5)
clf.fit(df_B_X,df_B_y_label)
tree.plot_tree(clf)
畫圖
os.chdir(r'D:\graphviz-2.38\graphviz-2.38\release\bin')
with open("tree1_liandong.dot",'w',encoding="utf-8") as f:
f = tree.export_graphviz(clf,out_file=f,
feature_names=df_B_X.columns,
class_names=['A~B','C','D~E'],
filled=True,rounded=True,special_characters=True
)
按照上述方法修改圖片中文顯示的問題,最終得到圖片如下。
