決策樹(Decision Tree)是一種非參數的有監督學習方法,它能夠從一系列有特征和標簽的數據中總結出決策規則,並用樹狀圖的結構來呈現這些規則,以解決分類和回歸問題。決策樹尤其在以數模型為核心的各種集成算法中表現突出。
開放平台:Jupyter lab
根據菜菜的sklearn課堂實效生成一棵決策樹。
三行代碼解決問題。
from sklearn import tree #導入需要的模塊 clf = tree.DecisionTreeClassifier() #實例化 clf = clf.fit(X_train,Y_train) #用訓練集數據訓練模型 result = clf.score(X_test,Y_test) #導入測試集,從接口中調用所需要信息
利用紅酒數據集畫出一棵決策樹。
從sklearn庫中引入決策樹、紅酒數據集
from sklearn import tree from sklearn.datasets import load_wine from sklearn.model_selection import train_test_split
根據不純度找出最佳節點和最佳的分歧方法。計算不純度有兩個指標:信息熵和基尼(Gini)指數。
例化決策樹,DecisionTreeClassifier是分類樹,DecisionTreeRegressor是回歸樹,tree.export_graphviz命令是將生成的決策樹導出為DOT格式,畫圖專用。通常使用基尼系數,數據維數很大,噪聲很大時使用基尼系數。維度低,數據比較清晰時,信息熵與基尼系數沒區別。當決策樹的擬合程度不夠時,使用信息熵。
下面例化決策樹,首先將數據分成訓練集和測試集。
Xtrain,Xtest,Ytrain,Ytest = train_test_split(wine.data, wine.target, test_size = 0.3)
注意分類的順序為XXYY
clf = tree.DecisionTreeClassifier(criterion = "entropy") clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #返回預測的准確度accuracy
我得到的分數為
效果還可以。
決策樹在此時已經生成,但是不太直觀,之后我們進行圖像的繪制。將特征和類別命名。
feature_name = ["酒精","蘋果酸","灰","灰的鹼性","鎂","總酚","類黃酮","非黃烷類酚類","花青素","顏色強度","色調","od280/od315稀疏葡萄酒","脯氨酸"] import graphviz dot_data = tree.export_graphviz(clf ,feature_names = feature_name ,class_names = ["琴酒","雪莉","貝爾莫得"] ,filled = True #填充顏色 ,rounded = True #畫出的方塊無棱角 ) graph = graphviz.Source(dot_data) graph
然后運行,我們就可以得到一棵樹啦(*^▽^*)。
運行[*zip(feature_name,clf.feature_importances_)] 可以看到每個屬性在分類時的比重。得到:
[('酒精', 0.03965653811434505),
('蘋果酸', 0.02068204382894391),
('灰', 0.0),
('灰的鹼性', 0.0),
('鎂', 0.06068969686746859),
('總酚', 0.0),
('類黃酮', 0.061368064261131956),
('非黃烷類酚類', 0.0),
('花青素', 0.0),
('顏色強度', 0.08690808214504504),
('色調', 0.03270487272137427),
('od280/od315稀疏葡萄酒', 0.26633722918973335),
('脯氨酸', 0.4316534728719579)]
可以看到並不是所有的特征都發揮着作用,只有八個特征有比重,且比重最大為脯氨酸,其次是od280/od315稀疏葡萄酒。
random_state & splitter 參數 (可以防止過擬合)
random_state 用來設置分枝中的隨機模式的參數,默認為None,在高維度時隨機性會表現更明顯,低維度數據隨機性幾乎不會顯現。輸入任意整數,會一直長出同一棵樹,讓模型穩定下來。
splitter也是用來控制決策樹中的隨機選項。"best":決策樹在分枝時雖然隨機,但是還會優先選擇更重要的特征進行分枝。"random"決策樹在分枝時會更加隨機,樹會更深,對訓練集的擬合度將會降低。
clf = tree.DecisionTreeClassifier(criterion = "entropy", random_state=10, splitter="random") clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #返回預測的准確度accuracy score
剪枝參數
max_depth 限制樹的最大深度,建議從=3開始嘗試。
min_samples_leaf 分枝會朝着滿足每個子節點都包含min_samples_leaf個樣本的方向發生,建議從=5開始。
min_samples_split 一個節點必須要包含至少min_samples_split個訓練樣本,這個節點才允許被分枝,否則分枝就不會發生。
max_features 限制分枝時考慮的特征個數,超過限制個數的特征會被舍棄。但強行設定這個參數會使模型學習不足。
min_impurity_decrease 限制信息增益的大小,信息增益小於設定數值的分枝不會發生。0.19版本
超參數曲線(確定最優的剪枝參數)
超參數的學習曲線,是一條以超參數的取值為橫坐標,模型的度量指標為縱坐標的曲線,它是用來衡量不同超參數取值下模型的表現的線。
引入matplotlib.pyplot庫,輸入代碼
import matplotlib.pyplot as plt test = [] for i in range(10): clf=tree.DecisionTreeClassifier(max_depth=i+1 ,criterion="entropy" ,random_state=0 ,splitter = "random" ) clf=clf.fit(Xtrain,Ytrain) score = clf.score(Xtest, Ytest) test.append(score) plt.plot(range(1,11),test,color='red',label='max_depth') plt.legend() plt.show()
得到:
從而能夠看到最大深度為多少時得到最高的分數。
目標權重參數
class_weight 完成樣本標簽平衡的參數。
min_weight_fraction_leaf 基於權重的剪枝參數。
重要屬性和接口
對決策樹來說,最重要的是feature_importances_,能夠查看各個特征對模型的重要性。常用接口還有apply和predict。
#apply 返回每個測試樣本所在的葉子節點的索引 clf.apply(Xtest) #predict 返回每個測試樣本的分類/回歸結果 clf.predict(Xtest)
總結:
七個參數:Criterion,兩個隨機性相關的參數(random_state,splitter),五個剪枝參數(max_depth, min_samples_split,min_sample_leaf,max_feature,min_impurity_decrease)
一個屬性:feature_importances_
四個接口:fit,score,apply,predict
回歸樹是如何工作的:
from sklearn.datasets import load_boston from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeRegressor boston = load_boston() regressor = DecisionTreeRegressor(random_state=0) cross_val_score(regressor, boston.data, boston.target, cv=10,
# ,scoring = "neg_mean_squared_error" 否則是R平方
) #交叉驗證s=cross_val_score的用法
訓練集和測試集的划分會干擾模型的結果,因此用交叉驗證n次的結果求出平均值,是對模型效果的一個更好的度量。
回歸樹案例:用回歸樹擬合正弦曲線
第一步:導入相應的庫
import numpy as np from sklearn.tree import DecisionTreeRegressor import matplotlib.pyplot as plt
第二步:創建一條含有噪聲的正弦曲線
先創建一組隨機的,分布在0-5上的橫坐標軸的取值(x),然后利用這些數生成對應正弦y值,接着再到y上去添加噪聲。
rng = np.random.RandomState(1) #生成隨機數種子 X = np.sort(5 * rng.rand(80,1), axis = 0) #不允許導入一維數據 同時排序 y = np.sin(X).ravel() #降維成一維 y[::5] += 3 * (0.5 - rng.rand(16)) #加上噪聲 5為步長 #np.random.rand(數組結構),生成隨機數組的函數 #np.xx.ravel() 降維函數,多次降維可降到一維
第三步:實例化&訓練模型
regr_1 = DecisionTreeRegressor(max_depth=2) regr_2 = DecisionTreeRegressor(max_depth=5) regr_1.fit(X,y) regr_2.fit(X,y)
第四步:測試集導入模型,預測結果
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis] y_1 = regr_1.predict(X_test) y_2 = regr_2.predict(X_test) #np.arrange(開始點,結束點,步長)生成有序數組的函數 #了解增維切片np.newaxis的用法 l = np.array([1,2,3,4]) l l.shape l[:,np.newaxis] l[:.np.newaxis].shape
第五步:繪制圖像
plt.figure() plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data") plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2) plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2) plt.xlabel("data") plt.ylabel("target") plt.title("Decision Tree Regression") plt.legend() plt.show()
得到圖像: