沒有樹木,哪來森林?談一談隨機(jī)森林算法的基礎(chǔ)——決策樹與熵

前面幾期文章我們通過簡單的KNN算法帶著大家入門了機(jī)器學(xué)習(xí),并通過幾個案例帶著大家熟悉了在Python中的調(diào)用sklearn下面封裝好的算法實施機(jī)器學(xué)習(xí)項目的一般流程。從本期開始我們進(jìn)入到下一個算法——決策樹(Deceious Tree)以及基于決策樹通過加入集成算法思想(ensemble learning)而形成的隨機(jī)森林(Random forest)和極限森林(Extreme forest)算法的學(xué)習(xí)。特別是隨機(jī)森林算法,在最近幾年的公開算法大賽中取得了比好的成績,知名度較高。后面我們也會重點(diǎn)介紹。

我們知道所謂的機(jī)器學(xué)習(xí),就是讓機(jī)器模擬人類的學(xué)習(xí)方法而獲取知識過程。把人類從經(jīng)驗/數(shù)據(jù)中歸納出來可以用與指導(dǎo)生產(chǎn)實踐或者做決策的知識/方法等這一過程歸抽象成算法,并通過編碼可以讓機(jī)器來執(zhí)行。這些機(jī)器通過執(zhí)行代碼,從而獲得我們所謂的智能。決策樹就是一個典型的例子。實際上我們每個人腦袋里面對某一事物進(jìn)行判斷很多時候就是一棵樹。比如辦公室新來了一位小伙伴,大家聚在一起八卦這位小伙伴薪資的時候,很多人肯定會問他的學(xué)歷啊工作年限啊是否是名校畢業(yè)等等,然后根據(jù)這些條件來估計薪資水平。把這些條件歸納起來并通過樹狀結(jié)果進(jìn)行分類或者擬合就是決策樹,如下面這張圖:


salary.JPG

在實際操作中我們還可以更多的分支,如是否是985學(xué)校畢業(yè),是否從大廠跳槽過來等等。我們可以想象:如果可以獲得的參考數(shù)據(jù)越多,我們的結(jié)論就會越準(zhǔn)確。這個和機(jī)器學(xué)習(xí)完全一致,即可以供算法學(xué)習(xí)的數(shù)據(jù)量越大,算法的結(jié)果越精確。這也是為什么近年來隨著大數(shù)據(jù)的出現(xiàn),智能算法精度越來越高。很多時候算法對事物趨勢的判斷已經(jīng)遠(yuǎn)遠(yuǎn)超越我們?nèi)祟?。國家大力發(fā)展5G,IoT, 大數(shù)據(jù)等基礎(chǔ)IT技術(shù)(新基建),其目的就是要搶占人工智能這一科技制高點(diǎn)。好了,又扯多了。
從上面這張圖我們可以看到?jīng)Q策樹算法是根據(jù)給定的數(shù)據(jù)集歸納出分類規(guī)則,并采用自頂向下的遞歸劃分(Recursive Partitioning)方式,以樹的形式展現(xiàn)出來。這其中,節(jié)點(diǎn)是樹的主體部分。一般來說,最上面一層為根節(jié)點(diǎn)(沒有父節(jié)點(diǎn)的節(jié)點(diǎn)),如上圖中的學(xué)歷菱形框。一個節(jié)點(diǎn)按照某個屬性分裂時,這個屬性就被成為分裂屬性,如上圖中學(xué)歷屬性和工作年限屬性。分到最后出現(xiàn)沒有子節(jié)點(diǎn)的節(jié)點(diǎn)時,該節(jié)點(diǎn)就被稱為葉子節(jié)點(diǎn)。

從這里我們可以看出決策樹分類算法的實現(xiàn)關(guān)鍵在于如何根據(jù)訓(xùn)練數(shù)據(jù)構(gòu)建一顆決策樹。而構(gòu)建決策樹的核心問題就在于如何選擇一個合適的分裂屬性進(jìn)行一次分裂以及如何制定合適的分裂標(biāo)準(zhǔn)(如工作年限分裂中的>3年和<3年)來產(chǎn)生相應(yīng)的分支。
上面的八卦薪資例子中,第一個分裂節(jié)點(diǎn)可以選擇學(xué)歷,也可以選擇工作年限。那么在實際操作中該如何選擇呢?這就時下面要說的信息熵(Information Entropy)的概念。算法會根據(jù)所有樣本 信息熵的變化(信息增益)來選擇最佳分類。 因而信息熵就是決策樹方法中分支產(chǎn)生的衡量標(biāo)準(zhǔn)之一。

信息熵來源熱力學(xué)中的熵(Entropy)的概念。最早由德國物理學(xué)家克勞修斯提出,用來表述某個體系的混亂程度。在此基礎(chǔ)上,美國的數(shù)學(xué)家,信息論的創(chuàng)始人香農(nóng)提出了信息熵的概念。它代表了一個給定數(shù)據(jù)集中的不確定性或者隨機(jī)性程度的度量。當(dāng)一個數(shù)據(jù)集中的記錄全部為同一類時,則沒有不確定性,此時熵為0。因此我們也可以把熵看成是信息的數(shù)學(xué)期望。若要求出熵的大小,則先要計算信息:

設(shè)某個事物具有n種相互獨(dú)立的可能結(jié)果,則信息的定義為:
l(x_i) = -log_2p(x_i)
為什么是以2為底的對數(shù)?這個可能和信息中的最小單位比特有關(guān)(一個比特只有0/1 2種狀態(tài)其中),其中x_i表示第i個分類,p(x_i)表示第i個分類的概率函數(shù),并且:\sum_{i=1}^np(x_i) = 1
由此,信息熵H(X)就可以表示為:
H(X) = - \sum_{i=1}^np(x_i) log_2p(x_i)
對于一個簡單的二元分類,此時n=2,那么其熵為:
H(X) = - p(x_1) log_2p(x_1) - p(x_2) log_2p(x_2)

通過信息熵我們可以精確的度量信息量的大小,香農(nóng)也因為這一成就成為信息學(xué)領(lǐng)域公認(rèn)的奠基人。我覺得這一成就完全可以媲美牛頓的萬有引力定律和愛因斯坦的質(zhì)能方程,前者確統(tǒng)一了宇宙所有天體的運(yùn)行規(guī)律,后者深刻揭示了質(zhì)量和能量只不過是同一事物不同的側(cè)面。

下面我們就用Python中內(nèi)置的鳶尾花數(shù)據(jù)集來實現(xiàn)決策樹算法。

1. 導(dǎo)入計算庫和數(shù)據(jù)

注意決策樹分類算法是放在sklearn.tree下面

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import datasets
from sklearn import tree

再把鳶尾花的數(shù)據(jù)導(dǎo)進(jìn)來

iris = datasets.load_iris()

X = iris['data']
y = iris['target']

iris_feature_names = iris.feature_names
iris_feature_names
print(iris_feature_names)
>>>['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

上面的代碼中,我們鳶尾花數(shù)據(jù)集中的樣本的4個維度的特征,單獨(dú)拿出來用于后面的散點(diǎn)圖矩陣分析和決策樹分裂屬性查看,直觀一點(diǎn)。這4個維度分別是花萼長度/寬度,花瓣長度/寬度。

2. 數(shù)據(jù)初步分析與查看

在之前的文章中,我們已經(jīng)使用過這個數(shù)據(jù)集了,知道了大體情況。這里就不再使用shape/size/等查看數(shù)據(jù)集了。我們直接把數(shù)據(jù)iris['data']和feature_names即4個維度的名稱合并成一個DataFrame,在調(diào)用pandas的散點(diǎn)圖矩陣觀察一下數(shù)據(jù)集

df = pd.DataFrame(iris['data'], columns = iris_feature_names)
df.head()
image.png
pd.plotting.scatter_matrix(df, c =iris['target'], figsize=(20, 20), marker='o', 
                                       hist_kwds={"bins": 20}, s=40, alpha=.8)

畫出4個維度的直方圖以及兩兩之間的散點(diǎn)圖,這樣可以直觀的看到數(shù)據(jù)分類情況,如下:

matrix.png

稍微觀察一下我們就可以發(fā)現(xiàn)使用petal length區(qū)分度最好,從上面圖中的第三行我們可以發(fā)現(xiàn)有一種花的petal length特別小,和其他兩種有很大的距離。另外petal width也有類似的情況(這兩個特征在直方圖中中間有斷開的地方,以這里作為標(biāo)準(zhǔn)可以很容易的裂分出一類)。下面我們就創(chuàng)建決策樹算法,看看算法是不是也是這么“想”的。

3. 構(gòu)建決策樹算法模型并查看模型精度

X_train, X_test, y_train, y_test = train_test_split(X, y , test_size = 0.2, random_state = 1024)

clf = DecisionTreeClassifier(criterion= 'entropy') #以entropy熵作為分裂標(biāo)準(zhǔn)構(gòu)建決策樹
clf.fit(X_train, y_train) #訓(xùn)練
y_ = clf.predict(X_test) #預(yù)測
tree_score = accuracy_score(y_test, y_) #查看模型預(yù)測結(jié)果的精度
print('該決策樹模型在測試集上的精度為: {:.2f}'.format(tree_score))
>>>該決策樹模型在測試集上的精度為: 1.00

之前我們反復(fù)的提到過在sklearn中構(gòu)建算法模型訓(xùn)練預(yù)測都是統(tǒng)一的格式,3-4行代碼搞定。上面也是用3行代碼完成了模型的創(chuàng)建/訓(xùn)練和預(yù)測,之后打印出來模型在測試集上精度。因為數(shù)據(jù)簡單,我們獲得了100%的精度,這個和之前的KNN差不多。
決策樹算法的構(gòu)建中同樣有很多參數(shù)可以調(diào),我們下次再細(xì)說。這里最后我們輸出一下上面算法的裂分條件和標(biāo)準(zhǔn),這個是決策樹比較贊的地方。我們可以直觀的看到算法是如何歸納訓(xùn)練數(shù)據(jù)集的數(shù)據(jù)特征并選擇最佳分裂條件進(jìn)行裂分,這個就是算法的學(xué)習(xí)過程。

plt.figure(figsize=(15,8))
_ = tree.plot_tree(clf, filled = True, feature_names=iris_feature_names,fontsize = 11)

結(jié)果如下圖:


tree_new.png

可以看到和我們之前預(yù)想的一致,算法第一步是按照petal length來裂分,直接得到一個葉子。我們在來套用熵的公式手算驗證一下圖中第一步得到的信息熵 entroy 為 1.584:

p1 = 39/120
p2 = 42/120
p3 = 39/120
H = -(p1 * np.log2(p1) + p2 * np.log2(p2) + p3 * np.log2(p3))
print(H)
>>>1.5840680553754911

結(jié)果和算法一致。有了這個樹,我們就可以清晰的知道算法是怎么分類的了。這個是決策樹比較好的地方,可視化/可解釋性強(qiáng)。有些算法我們不知道或者很難理解算法究竟做了什么來預(yù)測或者分類的,比如神經(jīng)網(wǎng)絡(luò)。
好了今天就到這里了,決策樹還有很多調(diào)參的內(nèi)容以及ID3,C4.5等以及隨機(jī)森林和極限樹等內(nèi)容我們以后在分享!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容