人人都在用的機器學習算法-決策樹

決策樹(DecisionTree)

這裏說幾個決策樹有關的概念:

  • 貪心算法:是指在對問題求解時,總是做出在當前看來是最好的選擇。不考慮總體的最優解,以每一步的局部最優解來模擬全局最優解。決策樹是典型的貪心算法,現在衆多的決策樹算法包括,ID3、C4.5和CART,都是在使用這一算法。

那麼對於決策樹來說,怎麼才能實現局部最優呢?需要有一些指標來幫助決策樹模型,判斷哪個條件是最重要的,對下面的例子來說:高,富,帥到底哪個是最重要的呢?決策樹爲了找出最佳節點和最佳的分枝⽅法,創建了幾個指標來幫助實現局部最優,簡單說一下,對公式感興趣的也可以自己搜搜看:

  • 信息熵:混亂度,不穩定度,不確定性越大,越混亂,則信息熵越大,反之,信息熵越小。我們當然是希望信息熵越小越穩定,越好,這樣我們預測的數據就更準確。
  • gini:常用,和信息熵相似,越小越好,只是值域不同,變化更平緩。
  • 分類誤差:決策樹中通常不使用,其對樣本數量的變動不敏感。

下圖是:各指標隨着單個節點中某一個變量佔比的變化圖
在這裏插入圖片描述

KNN算法思想

決策樹算法的原理,絕對是每個人都懂的,也每天都在使用的,簡單舉個例子大家就知道了:
每個人都不經意之間使用到決策樹,比如我想買房子:
1.先考慮要100平以上的,就會排除100平一下,在100平以上的房子中選擇,
2.在考慮有沒有學區,排除沒有學區的房子,在100平以上有學區的房子中選擇,
等等,這就是決策樹的算法思想

決策樹算法的構造, 實際上就是對原有數據集, 選取⼀定的屬性測試條件, 不斷進⾏切分的過程。
下面舉一個‘高富帥’的例子,來說下決策樹的一些基本概念:

節點 意義
根節點 沒有進邊,有出邊,一般指最初的,針對特徵的提問。例如正方形的“高嗎?”
中間節點 既有進邊也有出邊,進邊只有⼀條,出邊可以有很多條。例如橢圓形的的“帥嗎?”,“富嗎?”
葉⼦節點 有進邊,沒有出邊,例如菱形的的“註定單身”,“多人運動”
⼦節點和⽗節點 在兩個相連的節點中,更接近根節點的是⽗節點,另⼀個是⼦節點。例如:帥嗎?是富嗎?的父節點

在這裏插入圖片描述

決策樹的特點

  1. 過擬合:基本所有的決策樹在不加限制的情況下都會實現過擬合,達到測試集百分比的預測結果,過擬合一直是決策樹模型的比較困難的點。
  2. “王侯將相寧有種” :相較於knn的衆生平等,決策樹天生就認爲每個特徵有高低之分。
  3. “自成一家”:他是一個無參算法,不需要空間的假設。不太會受到離散值,缺失值的影響。
  4. 可理解性好,相較於其他算法,決策樹和人的思考方式比較相像,更容易解釋。

決策樹代碼實現

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)#訓練集分數

學習曲線
網格調參
這幾天太忙了,會慢慢把機器學習的算法都補出來的,前方應該有夢的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章