決策樹(DecisionTree)
這裏說幾個決策樹有關的概念:
- 貪心算法:是指在對問題求解時,總是做出在當前看來是最好的選擇。不考慮總體的最優解,以每一步的局部最優解來模擬全局最優解。決策樹是典型的貪心算法,現在衆多的決策樹算法包括,ID3、C4.5和CART,都是在使用這一算法。
那麼對於決策樹來說,怎麼才能實現局部最優呢?需要有一些指標來幫助決策樹模型,判斷哪個條件是最重要的,對下面的例子來說:高,富,帥到底哪個是最重要的呢?決策樹爲了找出最佳節點和最佳的分枝⽅法,創建了幾個指標來幫助實現局部最優,簡單說一下,對公式感興趣的也可以自己搜搜看:
- 信息熵:混亂度,不穩定度,不確定性越大,越混亂,則信息熵越大,反之,信息熵越小。我們當然是希望信息熵越小越穩定,越好,這樣我們預測的數據就更準確。
- gini:常用,和信息熵相似,越小越好,只是值域不同,變化更平緩。
- 分類誤差:決策樹中通常不使用,其對樣本數量的變動不敏感。
下圖是:各指標隨着單個節點中某一個變量佔比的變化圖
KNN算法思想
決策樹算法的原理,絕對是每個人都懂的,也每天都在使用的,簡單舉個例子大家就知道了:
每個人都不經意之間使用到決策樹,比如我想買房子:
1.先考慮要100平以上的,就會排除100平一下,在100平以上的房子中選擇,
2.在考慮有沒有學區,排除沒有學區的房子,在100平以上有學區的房子中選擇,
等等,這就是決策樹的算法思想
決策樹算法的構造, 實際上就是對原有數據集, 選取⼀定的屬性測試條件, 不斷進⾏切分的過程。
下面舉一個‘高富帥’的例子,來說下決策樹的一些基本概念:
節點 | 意義 |
---|---|
根節點 | 沒有進邊,有出邊,一般指最初的,針對特徵的提問。例如正方形的“高嗎?” |
中間節點 | 既有進邊也有出邊,進邊只有⼀條,出邊可以有很多條。例如橢圓形的的“帥嗎?”,“富嗎?” |
葉⼦節點 | 有進邊,沒有出邊,例如菱形的的“註定單身”,“多人運動” |
⼦節點和⽗節點 | 在兩個相連的節點中,更接近根節點的是⽗節點,另⼀個是⼦節點。例如:帥嗎?是富嗎?的父節點 |
決策樹的特點
- 過擬合:基本所有的決策樹在不加限制的情況下都會實現過擬合,達到測試集百分比的預測結果,過擬合一直是決策樹模型的比較困難的點。
- “王侯將相寧有種” :相較於knn的衆生平等,決策樹天生就認爲每個特徵有高低之分。
- “自成一家”:他是一個無參算法,不需要空間的假設。不太會受到離散值,缺失值的影響。
- 可理解性好,相較於其他算法,決策樹和人的思考方式比較相像,更容易解釋。
決策樹代碼實現
PS:在現在的競賽中大多不會單獨使用決策樹模型進行預測,因爲隨機森林太厲害了。
我這裏用網格搜索的方法試着給決策樹調參看一下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#全部行都能輸出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
#顯示中文,解決圖中無法顯示中文的問題
plt.rcParams['font.sans-serif']=['Simhei']
plt.rcParams['axes.unicode_minus']=False
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris # 用的數據集, 鳶尾花集
# 導入數據,切分測試集數據集
iris = load_iris()
X = pd.DataFrame(data = iris.data, columns=iris.feature_names)
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
#學習曲線初步調參
train_score_list = []
test_score_list = []
cross_score_list = []
for i in range(1,10):
dtc = DecisionTreeClassifier(max_depth=i)# 調最大深度
dtc.fit(X_train, y_train)
train_score = dtc.score(X_train, y_train)
test_score = dtc.score(X_test, y_test)
cross_score = cross_val_score(dtc, X_train, y_train, cv=5).mean()
train_score_list.append(train_score)
test_score_list.append(test_score)
cross_score_list.append(cross_score)
#畫圖
plt.plot(range(1,10 ), train_score_list , label='train_score' )
plt.plot(range(1,10 ), test_score_list , label='test_score' )
plt.plot(range(1,10 ), cross_score_list , label='cross_score' )
plt.legend()
#網格搜索多參數調參
dtc = DecisionTreeClassifier(random_state=666)
grid_range = {
"max_depth":[2,3,4],
"min_samples_leaf":range(2, 40,5),
"max_leaf_nodes":range(3, 8),
"min_samples_split":range(10, 31, 2)}
grid = GridSearchCV(dtc , param_grid=grid_range, n_jobs=-1, verbose=2, cv=5 ).fit(X_train, y_train)
grid.best_score_# 最優分數
grid.best_params_# 最優分數參數組合
grid.score(X_test, y_test)#測試集分數
grid.score(X_train, y_train)#訓練集分數
這幾天太忙了,會慢慢把機器學習的算法都補出來的,前方應該有夢的。