帶你走進(jìn)sklearn系列1
資料來源:菜菜B站視頻
文章內(nèi)容:決策樹的基本概念和實戰(zhàn)應(yīng)用。不會展示公式原理,偏重于實戰(zhàn)應(yīng)用。
無意中翻到了菊安醬和菜菜的博客,大家可以去看一下:https://www.cnblogs.com/juanjiang/p/11003369.html
概述
決策樹是一種非參數(shù)的有監(jiān)督學(xué)習(xí)算法,非參數(shù)是說參數(shù)數(shù)量會隨著訓(xùn)練樣本增長的算法。
具體可以去看:https://www.cnblogs.com/wwwjjjnnn/p/9126906.html
核心問題
- 誰是最佳分枝點
- 什么時候停止分枝
模塊sklearn.tree
共包含4種樹和3種樹的輸出形式,官方教程:https://scikit-learn.org/stable/modules/classes.html#module-sklearn.tree
- tree.DecisionTreeClassifier() 分類樹 ****今日重點**
- tree.DecisionTreeRegressor() 回歸樹
- tree.ExtraTreeClassifier() 高隨機(jī)版本的分類樹
- tree.ExtraTreeRegressor() 高隨機(jī)版本的回歸樹
- tree.export_graphviz(decision_tree) 輸出DOT格式的圖
- tree.export_text(decision_tree) 輸出決策樹規(guī)則的文本
- tree.plot_tree(decision_tree) 畫決策樹
重要參數(shù)--8個
class sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort='deprecated', ccp_alpha=0.0)
1.criterion
用來決定不純度的計算方法:entropy、gini。樹中的每一個節(jié)點都有不純度,葉子節(jié)點的不純度最低。
一般默認(rèn)使用gini,當(dāng)決策樹擬合程度不夠時,再試試信息熵,信息熵對訓(xùn)練集擬合的比較精細(xì),但往往也容易過擬合,兩者基本沒太大差別。選擇不純度最低的節(jié)點(就是最純的,最容易直接分類的特征)進(jìn)行分枝,決策樹在分枝時,其實使用的是信息增益。
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
wine = load_wine()
利用紅酒數(shù)據(jù)集建一棵樹,數(shù)據(jù)集中字段包括:wine.data,wine.target,wine.target_names,wine.feature_names,該數(shù)據(jù)集是一個三分類數(shù)據(jù)。
# 做成一個表,來瞅一下,最后一列就是標(biāo)簽
import pandas as pd
data = pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
data.head(3)
# 劃分?jǐn)?shù)據(jù)集,注意前面一定是xxyy,test_size可以自己設(shè)定7:3還是8:2
x_train,x_test,y_train,y_test = train_test_split(wine.data,wine.target,test_size=0.3)
print("x_train的維度{},wine.date的維度{}".format(x_train.shape,wine.data.shape))
x_train的維度(124, 13),wine.date的維度(178, 13)
2.random_state & splitter
sklearn通過在分枝時隨機(jī)選取部分特征進(jìn)行優(yōu)化,進(jìn)而建立很多棵樹,返回最好的樹。
在高維度的數(shù)據(jù)中,每次運(yùn)行下面的模型,會返回不同的分?jǐn)?shù)。為保持結(jié)果穩(wěn)定,設(shè)定random_state參數(shù)。
splitter控制隨機(jī)選項,有兩個參數(shù):'best'根據(jù)重要程度選取特征;'random'在分枝時更隨機(jī),對訓(xùn)練集的擬合度會降低。 所以如果你本身特征就比較多,為了防止過擬合可以設(shè)置這兩個參數(shù)。
# 建??匆幌?
clf = tree.DecisionTreeClassifier(criterion='entropy'
,random_state=30
,splitter='random'
)
clf = clf.fit(x_train,y_train)
score = clf.score(x_test,y_test)
print('模型分?jǐn)?shù):%.4f' %score)
import graphviz
feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','飛黃烷類酚類','花青素','顏色強(qiáng)度','色調(diào)','稀釋葡萄酒','脯氨酸']
dot_data = tree.export_graphviz(clf
,feature_names=feature_name
,class_names=['琴酒','雪莉','貝爾摩德']
,filled=True # 顏色填充
,rounded=True # 圓角
)
graph = graphviz.Source(dot_data)
graph
graphviz要自己另外安裝,記得加入path。
查看特征排名
# 特征重要性的排名
clf.feature_importances_
# *zip()進(jìn)行解壓
[*zip(feature_name,clf.feature_importances_)]
3.剪枝參數(shù)(5個)
- max_depth 限制樹的深度,在高維度低樣本的訓(xùn)練中非常有效。建議從=3開始嘗試,看擬合效果再決定是否增加深度。
-
min_samples_leaf
節(jié)點分枝后的每個子節(jié)點包含的樣本數(shù)必須包含的樣本個數(shù),一般搭配max_depth使用,建議從=5開始使用。 -
min_samples_split
一個節(jié)點必須包含的樣本數(shù),小于這個樣本數(shù),就不會允許繼續(xù)分枝。 -
max_features
限制分枝時考慮的特征個數(shù),是一個比較暴力的強(qiáng)行使決策樹停下的參數(shù)。如果希望降維選取重要特征,建議改用PCA、ICA或其他特征選擇模塊中的降維算法,盲目限制該參數(shù),可能會使模型學(xué)習(xí)能力不足。 -
min_impurity_decrease
當(dāng)信息增益小于限定的數(shù)值時,不會再分枝。
一般來講max_depth+min_samples_leaf|min_samples_split就可以完成調(diào)參,后面的參數(shù)設(shè)置屬于精修范圍。
# 對訓(xùn)練集的擬合程度---“太完美了”
train_score=clf.score(x_train,y_train)
train_score
進(jìn)行剪枝,參數(shù)是隨便修改的,該結(jié)果并不是最優(yōu) ,重點看參數(shù)設(shè)置后的變化
cut_clf = tree.DecisionTreeClassifier(criterion='entropy'
,random_state=30
,splitter='random'
,max_depth=4
,min_samples_leaf=5
,min_samples_split=45
)
cut_clf = cut_clf.fit(x_train,y_train)
cut_score = cut_clf.score(x_test,y_test)
print('模型分?jǐn)?shù):%.4f' %cut_score)
cut_dot_data = tree.export_graphviz(cut_clf
,feature_names=feature_name
,class_names=['琴酒','雪莉','貝爾摩德']
,filled=True # 顏色填充
,rounded=True # 圓角
)
cut_graph = graphviz.Source(cut_dot_data)
cut_graph
如何調(diào)參
學(xué)習(xí)曲線的使用
以超參數(shù)的取值為橫坐標(biāo),模型的度量值為縱坐標(biāo)。
import matplotlib.pyplot as plt
%matplotlib inline
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth=i+1
,criterion='entropy'
,random_state=30
)
clf = clf.fit(x_train,y_train)
score = clf.score(x_test,y_test)
test.append(score)
plt.plot(range(1,11),test,color='red',label='max_depth')
plt.legend()
plt.show()

- 剪枝參數(shù)不一定提高模型在測試集上的表現(xiàn),這取決于數(shù)據(jù)本身。
- 遺留問題:多參數(shù)調(diào)參(后面補(bǔ)上)
目標(biāo)權(quán)重參數(shù)
-
class_weight & min_weight_fraction_leaf
當(dāng)樣本類別不平衡時設(shè)置的參數(shù),默認(rèn)為None,所有標(biāo)簽具有相同權(quán)重。
樣本加權(quán)之后使用min_weight_fraction_leaf配合調(diào)參。
重要屬性
- feature_importances_
訓(xùn)練之后,調(diào)用clf.feature_importances_查看特征重要程度。
與特征名一起解壓,得到(特征,權(quán)重)元組。
重要接口
- fit()
- score()
- apply()
返回樣本點所在葉子節(jié)點的索引。 - predict()
返回樣本分類/回歸的結(jié)果。
總結(jié)
決策樹一共講了8個參數(shù),1個屬性,4個接口 。
| 8個參數(shù) | 4個接口 | 1個屬性 |
|---|---|---|
| criterion計算不純度 | fit() | feature_importances_ |
| random_state & splitters隨機(jī)項設(shè)置 | score() | |
| max_depth剪枝參數(shù) | apply() | |
| min_samples_leaf & min_samples_split 剪枝參數(shù) | predict() | |
| max_features & min_impurity_decrease 剪枝參數(shù) | ||
| class_weight & min_weight_fraction_leaf 類別權(quán)重 |