決策樹(中):CART,一顆是迴歸樹,另一顆是分類樹

決策樹(中):CART,一顆是迴歸樹,另一顆是分類樹

基於信息度量的不同方式,把決策樹分爲ID3算法、C4.5算法和CART算法,CART算法叫做分類迴歸樹,ID3和C4.5算法可以生成二叉樹或多叉樹,而CART只支持二叉樹,既可以作分類樹,又可以作迴歸樹

什麼是分類樹?什麼是迴歸樹?

img

能看到不同職業的人,年齡也不同,學習時長也不同,如果構造一顆決策樹,想要基於數據判斷這個人職業身份,就屬於分類樹,因爲是從幾個分類中來做選擇,如果給定了數據,想要預測這個人的年齡,那就屬於迴歸樹。

所謂分類樹就是面向分類的,每個決策樹最末端的葉子結點出來的是一個分類標籤,不是0就是1或者2等類別。迴歸樹就是面向迴歸的,迴歸就是擬合函數一樣,輸出連續值,比如根據一大堆當天的特徵輸出明天的氣溫,氣溫是每個樣本唯一輸出的值,只不過輸出的值根據特徵的不一樣輸出值不一樣而已,但是它們輸出的意義是一樣的,那就是都是氣溫。
分類樹可以處理離散數據,也就是數據種類有限的數據,它輸出的是樣本的類別,而回歸樹可以對連續型的數值進行預測,也就是數據在某個區間內都有取值的可能,它輸出的是一個數值

CART分類樹的工作流程

決策樹的核心就是尋找純淨的劃分,在屬性選擇上,通過統計“不純度”來判斷的,ID3是基於信息增益做判斷,C4.5在ID3基礎上做引進,提出了信息增益率的概念,CART分類樹屬性選擇的指標採用的是基尼係數,基尼係數本身反映了樣本的不確定度,當基尼係數越小的時候說明樣本之間的差異性小,不確定程度低,分類的過程本身是一個不確定度降低的過程,即純度提升過程,所以CART算法在構造分類樹的時候,會選擇基尼係數最小的屬性作爲屬性的劃分

img

節點t的基尼係數爲1減去各類別CK概率平方和,p(Ck|t)表示節點t屬於類別Ck的概率

計算兩個集合的基尼係數分別是:

  • 集合1:6個都去打籃球
  • 集合2:3個去打籃球,3個不去打籃球

針對集合1,P(Ck|t) = 1,所以GINI(t) = 1-1=0

針對集合2,P(C1|t)=0.5,P(C2|t)=0.5,GINI(t)=1-(0.5*0.5+0.5*0.5)=0.5,集合1的基尼係數最小,證明樣本最穩定,在CART算法中,基於基尼係數對特徵屬性進行二元分裂,屬性A將節點D劃分爲D1、D2

D:(9個打籃球,3個不打籃球) -> D1:6個打籃球

​ D2:3個打籃球,3個不打

節點D的基尼係數等於子節點D1和D2的歸一化基尼係數之和img

歸一化基尼係數代表的是每個子節點的基尼係數乘以該節點佔整體父親節點D中的比例,所以在屬性A的劃分下,節點D的基尼係數爲:

img

節點D被屬性A劃分後的基尼係數越大,樣本集合的不確定性越大,就是不純度越高

如何使用CART算法來創建分類樹

CART分類樹可以在Python的sklearn中,創建CART分類樹,直接使用DecisionTreeClassifier這個類,創建這個類的時候,默認criterion這個參數等於gini,就是按照基尼係數來選擇屬性劃分,即默認採用CART分類樹

用CART分類樹,給iris數據集構造一顆分類決策樹

# encoding=utf-8
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
# 準備數據集
iris=load_iris()
# 獲取特徵集和分類標識
features = iris.data
labels = iris.target
# 隨機抽取33%的數據作爲測試集,其餘爲訓練集
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size=0.33, random_state=0)
# 創建CART分類樹
clf = DecisionTreeClassifier(criterion='gini')
# 擬合構造CART分類樹
clf = clf.fit(train_features, train_labels)
# 用CART分類樹做預測
test_predict = clf.predict(test_features)
# 預測結果與測試集結果作比對
score = accuracy_score(test_labels, test_predict)
print("CART分類樹準確率 %.4lf" % score)

CART分類樹準確率 0.9600

train_test_split抽取一部分作爲測試集,可以得到測試集合訓練集

使用clf=DecisionTreeClassifier(criterion=‘gini’)初始化一棵CART分類樹,就可以對分類樹進行訓練

使用clf.fit(train_features,train_labels) 將訓練集的特徵值和分類標識作爲參數進行擬合,得到CART分類樹

使用clf.predict(test_features)進行預測,傳入測試集的特徵值,得到測試結果test_predict

最後使用accuracy_score(test_labels,test_predict)傳入測試集的預測結果與實際結果作爲參數得到準確率score

CART迴歸樹的工作流程

CART迴歸樹劃分數據集的過程和分類樹的過程是一樣的,只是迴歸樹得到的預測結果是連續值,且評判“不純度”的指標不同,在CART迴歸樹中,根據樣本的混亂程度就是樣本的離散程度來評價“不純度”

樣本的離散程度的計算方式是先計算所有樣本的均值,然後計算每個樣本值到均值的差值,假設x爲樣本的個體,均值爲μ,爲了統計樣本的離散程度,可以取差值的絕對值,或者方差

差值的絕對值爲樣本值減去樣本均值的絕對值|x-μ|,方差爲每個樣本值減去樣本均值的平方和除以樣本個數

img

兩種節點劃分的標準分別對應兩種目標函數最優化的標準,即用最小絕對偏差LAD,或者用最小二乘偏差LSD,通常使用LSD更常見一些

如何使用CART迴歸樹做預測

用sklearn自帶的波士頓房價數據集,該數據集給出了影響房價的一些指標,比如犯罪率、房產稅等,最後給出了房價,使用CART迴歸樹做預測:

# encoding=utf-8
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.metrics import r2_score,mean_absolute_error,mean_squared_error
from sklearn.tree import DecisionTreeRegressor
# 準備數據集
boston=load_boston()
# 探索數據
print(boston.feature_names)
# 獲取特徵集和房價
features = boston.data
prices = boston.target
# 隨機抽取33%的數據作爲測試集,其餘爲訓練集
train_features, test_features, train_price, test_price = train_test_split(features, prices, test_size=0.33)
# 創建CART迴歸樹
dtr=DecisionTreeRegressor()
# 擬合構造CART迴歸樹
dtr.fit(train_features, train_price)
# 預測測試集中的房價
predict_price = dtr.predict(test_features)
# 測試集的結果評價
print('迴歸樹二乘偏差均值:', mean_squared_error(test_price, predict_price))
print('迴歸樹絕對值偏差均值:', mean_absolute_error(test_price, predict_price)) 

[‘CRIM’ ‘ZN’ ‘INDUS’ ‘CHAS’ ‘NOX’ ‘RM’ ‘AGE’ ‘DIS’ ‘RAD’ ‘TAX’ ‘PTRATIO’ ‘B’ ‘LSTAT’]
迴歸樹二乘偏差均值: 23.80784431137724
迴歸樹絕對值偏差均值: 3.040119760479042

首先加載了波士頓房價數據集,得到特徵集和房價。通過train_test_split抽取一部分當做測試集,其餘作爲訓練集,使用dtr=DecisionTreeRegressor()初始化一棵CART迴歸樹,使用dtr.fit(train_features,train_price)函數將訓練集的特徵值和結果作爲參數進行擬合,得到CART迴歸樹,使用dtr.predict(test_features)進行預測,傳入測試集的特徵值,得到預測結果predict_price,最後求得這棵迴歸樹的二乘偏差均值以及絕對值偏差均值

CART決策樹的剪枝

採用CCP方法,是一種後剪枝的方法,叫做代價複雜度,這種剪枝方式用到一個指標叫做節點的表面誤差率增益值,依次作爲剪枝前後誤差的定義

img

Tt表示以t爲根節點的子樹,C(Tt)表示節點t的子樹沒被裁減時子樹Tt的誤差,C(t)表示節點t的子樹被剪枝後節點t的誤差,|Tt|代子樹Tt的葉子樹,剪枝後,T的葉子樹減少了|Tt|-1

外鏈圖片轉存中…(img-MoUK3joS-1584929702408)]

Tt表示以t爲根節點的子樹,C(Tt)表示節點t的子樹沒被裁減時子樹Tt的誤差,C(t)表示節點t的子樹被剪枝後節點t的誤差,|Tt|代子樹Tt的葉子樹,剪枝後,T的葉子樹減少了|Tt|-1

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