python实现决策树算法sklearn_python sklearn-05:决策树及随机森林
1.決策樹
2.隨機森林
1.決策樹(decision tree)
決策樹一種簡單的非線性模型,用來解決回歸與分類問題。
通常是重復的將訓練集解釋變量分割成子集的過程。決策樹的節點用方塊表示,用來測試解釋變量。
每個節點向下的邊表示不同決策產生結果。訓練集的樣本由決策結果分成不同的子集。例如,一個節點測試解釋變量的值是否超過的限定值。如果沒有超過,則進入該節點的右側子節點;如果超過,則進入左側子節點。子節點的運行原理和前面的一樣,直到終止條件(stopping criterion)滿足才停止。在分類任務中,包含在葉子節點中的樣本響應變量的值的平均值作為響應變量的估計值。
決策樹建立之后,做決策的過程就是把測試樣本放進決策樹沿著邊不斷前進,直到一個葉子被觸及才停止前進。
訓練決策樹:
常用的方法:
ID3(Iterative Dichotomiser 3,迭代二叉樹3代),決策樹需要對每條邊的解釋變量進行檢查。每條邊的下一個節點由測試結果決定。決策樹也是通過對解釋變量序列的逐條測試獲取響應變量結果的。那么,哪個解釋變量應該先測試?如果子集成員種類不同,我們還是不能確定種類。我們還需要避免創建那種測試,這些測試極少可以分出一個樣本的種類,也不能降低分類不確定性。能夠降低分類不確定性的測試通常都是最好的測試。
我們通常用熵(entropy)來度量信息的不確定性。以比特(bits)為計量單位,熵量化了一個變量的不確定性。熵計算公式如下所示:
其中,n 是樣本的數量,P(xi) 是第 個樣本的概率。b 一般取 2,e 或10 。因為對數函數中真數小于1
則對數值為0,因此,公式前面加符號使熵為正數。
例如,一個硬幣投擲一次事件發生后一般有兩種可能:正面或反面。正面朝上的概率是0.5,反面朝
上的概率也是0.5。那么一個硬幣投擲一次的結果這個變量的熵:
H(X) = ?(0.5 0.5 + 0.5 0.5) = 1.0
也就是說,兩個等概率的可能值,正面和反面,只需要一個比特。如果是兩個硬幣投擲一次事件發生
后一般有四種可能:正面正面,正面反面,反面反面,反面正面,每種可能的概率是0.25。其熵為:
如果硬幣的兩面相同,那么表示其可能值的變量熵為0比特,也就是說,結果是確定的,變量再也不
會產生新信息量了。熵還可以用小數值表示。比如,一個不正常的硬幣,其正反面的材質不同,一邊
重一邊輕。導致其投擲后正面朝上的概率0.8,反面朝上概率0.2。那么其熵為:
一個不正常的硬幣投擲后其結果的熵是一個小數。雖然兩種結果都有可能,但是因為其中一種可能性
更大,所有不確定性減小了。
而我們的問題并沒有消除許多可能性。因此,要用一種方法來合理度量熵的降幅,這個方法稱為信息增益(information gain)。信息增益是父節點熵,用 表示與其子節點熵的加權均值的差,計算公式如下:
其中,
?表示解釋變量 的樣本 。
表示解釋變量 的值等于 樣本數量。
是解釋變量 的值等于 樣本熵。
還有很多算法也可以實現決策樹,C4.5算法是ID3的改進版,可以用來處理連續的解釋變量并考慮特征值丟失。C4.5算法可以修剪(prune)決策樹,修剪是通過更少的葉節點來替換分支,以縮小決策樹的規模。scikit-learn的決策樹實現算法是CART(Classification and Regression Trees,分類與回歸樹)算法,CART也是一種支持修剪的學習算法。
基尼不純度
除了最大信息增益建立決策樹,還可以用基尼不純度(Gini impurity),度量一個集合中每種類型的比例。基尼不純度格式如下:
其中,j 是類型的數量,t 是節點樣本的子集,P(i|t) 是從節點子集中選擇一個類型 的概率。
可以看出,如果集合中只有一類,那么基尼不純度值為0。和熵一樣,當每個類型概率相同時,基尼
不純度最大。此時,基尼不純度的最大值有類型的數量決定:
我們的例子有兩種類型,所有基尼不純度的最大值是0.5。scikit-learn研究決策樹的算法,既支持信
息增益,也支持基尼不純度。到底用哪種方法并沒有規定,實際上,它們產生的結果類似。一般的決
策樹都是兩個都用,比較一下結果,哪個好用哪個。
#scikit-learn決策樹
用scikit-learn的決策樹來做一個廣告屏蔽程序,這個程序可以預測出網頁上的圖片是廣告
還是正常內容。被確認是廣告的圖片通過調整CSS隱藏。
數據源:互聯網廣告數據集(Internet
Advertisements Data Set) (http://archive.ics.uci.edu/ml/datasets/Internet+Advertisements)
來實現分類器,里面包含了3279張圖片。不過類型的比例并不協調,459幅廣告圖片,2820幅正常內容。決
策樹學習算法可以從比例并不協調的數據集中生成一個不平衡的決策樹(biased tree)。
首先對模型進行評估,本例的解釋變量就是圖片的尺寸,網址鏈接里的單詞,以及圖片標簽周圍的單詞。響應變量就是圖片的類型。解釋變量已經被轉換成特征向量了。前三個特征值表示寬度,高度,圖像縱橫比(aspect ratio)。剩下的特征是文本變量的二元頻率值。下面,用網格搜索來確定決策樹模型最大最優評價效果(F1 score)的超參數,然后把決策樹用在測試集進行效果評估。
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
#讀取數據,源數據是zip,可以解壓后再讀取,也可以import zipfile,讀取壓縮數據
df = pd.read_csv(r'D:\每日工作\學習筆記\test\mlslpic\ad-dataset\ad.data', header=None)
explanatory_variable_columns = set(df.columns.values)
response_variable_column = df[len(df.columns.values)-1]
# The last column describes the targets
explanatory_variable_columns.remove(len(df.columns.values)-1)
y = [1 if e == 'ad.' else 0 for e in response_variable_column]
X = df.loc[:, list(explanatory_variable_columns)]
X.replace(to_replace=' *\?',value=-1, regex=True, inplace=True)
X_train,X_test, y_train, y_test = train_test_split(X,y)
pipeline = Pipeline([
('clf',DecisionTreeClassifier(criterion='entropy'))
])
parameters = {
'clf__max_depth': (150, 155, 160),
'clf__min_samples_split': (1, 2, 3),
'clf__min_samples_leaf': (1, 2, 3)
}
grid_search = GridSearchCV(pipeline, parameters, n_jobs=-1,verbose=1, scoring='f1')
grid_search.fit(X_train, y_train)
print ('最佳效果:%0.3f' %grid_search.best_score_)
print('最優參數')
best_parameters = grid_search.best_best_parameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
print('\t%s: %r' % (param_name, best_parameters[param_name]))
predictions = grid_search.predict(X_test)
print (classification_report(y_test, predictions))
precision recall f1-score support
out:
Fitting 3 folds for each of 27 candidates, totalling 81 fits
[Parallel(n_jobs=-1)]: Done 42 tasks | elapsed: 8.8s
[Parallel(n_jobs=-1)]: Done 81 out of 81 | elapsed: 13.9s finished
最佳效果:0.888
clf__max_depth: 150
clf__min_samples_leaf: 3
clf__min_samples_split: 3
0 0.98 0.98 0.98 710
1 0.87 0.85 0.86 110
avg / total 0.96 0.96 0.96 820
#這個分類器發現了測試集中90%的廣告,真廣告中87%被模型發現了。
2.決策樹集成,隨機森林
集成學習方法將一堆模型組合起來使用,比單個模型可以獲取更好的效果。
隨機森林(randomforest) 是一種隨機選取訓練集解釋變量的子集進行訓練,獲得一系列決策樹的集合的方法。
隨機森林通常用其決策樹集合里每個決策樹的預測結果的均值或眾數作為最終的預測值。
scikit-learn里的隨機森林使用均值作為預測值。隨機森林相比單一決策樹,不太會受到擬合過度的影響,因為隨機森林的
每個決策樹都看不到訓練集的全貌,只是訓練一部分解釋變量數據,不會記憶訓練集的全部噪聲。
用隨機森林升級廣告屏蔽程序,把前面DecisionTreeClassifier替換成RandomForestClassifier就可以了。仍然用網格搜索來探索最優超參數。
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
#讀取數據,源數據是zip,可以解壓后再讀取,也可以import zipfile,讀取壓縮數據
df = pd.read_csv(r'D:\每日工作\學習筆記\test\mlslpic\ad-dataset\ad.data', header=None)
explanatory_variable_columns = set(df.columns.values)
response_variable_column = df[len(df.columns.values)-1]
# The last column describes the targets
explanatory_variable_columns.remove(len(df.columns.values)-1)
y = [1 if e == 'ad.' else 0 for e in response_variable_column]
X = df.loc[:, list(explanatory_variable_columns)]
X.replace(to_replace=' *\?',value=-1, regex=True, inplace=True)
X_train,X_test, y_train, y_test = train_test_split(X,y)
pipeline = Pipeline([
('clf',RandomForestClassifier(criterion='entropy'))
])
parameters = {
'clf__max_depth': (150, 155, 160),
'clf__min_samples_split': (1, 2, 3),
'clf__min_samples_leaf': (1, 2, 3)
}
grid_search = GridSearchCV(pipeline, parameters, n_jobs=-1,verbose=1, scoring='f1')
grid_search.fit(X_train, y_train)
print ('最佳效果:%0.3f' %grid_search.best_score_)
print('最優參數')
best_parameters = grid_search.best_best_parameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
print('\t%s: %r' % (param_name, best_parameters[param_name]))
predictions = grid_search.predict(X_test)
print (classification_report(y_test, predictions))
out:
Fitting 3 folds for each of 27 candidates, totalling 81 fits
[Parallel(n_jobs=-1)]: Done 42 tasks | elapsed: 8.3s
[Parallel(n_jobs=-1)]: Done 81 out of 81 | elapsed: 12.3s finished
最佳效果:0.923
clf__max_depth: 150
clf__min_samples_leaf: 1
clf__min_samples_split: 3
precision recall f1-score support
0 0.98 0.99 0.98 710
1 0.91 0.87 0.89 110
avg / total 0.97 0.97 0.97 820
#這個分類器發現了測試集中91%的廣告,各類指標相比單一決策樹都有明顯改善。精確率和召回率都提升到97%。
3.總結:
決策樹的優劣勢
決策樹的用法更簡單。首先,決策樹對數據沒有零均值,均方差的要求。而且可以容忍解釋變量值的缺失,雖然現在的scikit-learn還沒實現這一特點。決策樹在訓練的時
候可以忽略與任務無關的解釋變量。
小型決策樹很容易理解,而且可以通過scikit-learn的tree模塊里的export_graphviz函數生成圖形,可視化效果好。決策樹的分支都有著邏輯上的聯接關系,很容易通過流程圖畫出來。另外,決策
樹支持多輸出任務,單一決策樹可以用于多類分類,不需要使用one-versus-all策略。
決策樹是一種積極學習方法(eager learner),必須在它們可以用于預測測試集任務時,先從訓練集建立一個與后面的需求無關的模型,但是模型一旦建好它們可以很快的預
測出結果。相反,有些算法是消極學習方法(lazy learners),像K最近鄰(K-Nearest Neighbor,KNN)分類算法,它們必須等到有了訓練集數據的預測需求,才會開始學習整個數據的特征。
消極學習方法不需要花時間訓練預測能力,但是比積極學習方法預測速度慢。
決策樹比之前介紹的算法更容易擬合過度,因為它們可以通過精確的描述每個訓練樣本的特征,構建出復雜的決策樹,從而忽略了一般性的真實關聯關系。有一些技術可以修正決策樹的擬合過度。
修剪就是一個常用的策略,將決策樹里一些最高的子節點和葉子節點剪掉,但是目前scikit-learn還沒有相應的實現。但是,類似的效果可以通過設置決策樹最大深度,或者限定只有當決策樹包含的訓練
樣本數量超過限定值時才創建子節點。DecisionTreeClassifier和DecisionTreeRegressor類都有這樣的參數可以設置。另外,隨機森林決策樹也可以消除擬合過度。
像ID3這樣的決策樹學習算法是貪婪的(greedy)。它們充分的學習有時會深陷于局部最優的美夢,但是不能保證生成最優決策樹。ID3通過選擇解釋變量序列進行測試。一個解釋變量被選中是因為它比其他解釋變量更大幅度的降低了不確定性。但是,有可能全局最優的決策并非局部最優。
在例子中,決策樹的規模并不重要,因為我們可以獲取所有節點。但是,在現實應用中,決策樹的規模被修剪以及其他技術限制。而決策樹經過修剪后的不同形狀會產生不同的效果。實際上,由信息增益和基尼不純度啟發式方法計算出的局部最優決策通常都會生成一個可行的決策樹。
總結
以上是生活随笔為你收集整理的python实现决策树算法sklearn_python sklearn-05:决策树及随机森林的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王者荣耀怎么用流量下载
- 下一篇: 大话西游手游时间服是什么意思(《大话西游