大白话5分钟带你走进人工智能-第二十六节决策树系列之Cart回归树及其参数(5)...
??????????????????????????????????????????????? 第二十六節(jié)決策樹(shù)系列之Cart回歸樹(shù)及其參數(shù)(5)
上一節(jié)我們講了不同的決策樹(shù)對(duì)應(yīng)的計(jì)算純度的計(jì)算方法,其實(shí)都是針對(duì)分類(lèi)來(lái)說(shuō),本節(jié)的話(huà)我們講解回歸樹(shù)的部分。
目錄
1-Cart回歸樹(shù)的概念
1-代碼詳解
?
1-Cart回歸樹(shù)的概念
對(duì)于回歸樹(shù)來(lái)說(shuō),之前咱們講的三個(gè)決策樹(shù)(ID3,C4.5和Cart樹(shù))里只有CART樹(shù)具有回歸上的意義,其實(shí)它無(wú)非就是把分裂條件給變了變,把葉子節(jié)點(diǎn)的表達(dá)給變了變。剩下的全部過(guò)程都是和分類(lèi)樹(shù)沒(méi)有區(qū)別的。它的分裂條件變成什么了呢?分裂條件仍然是通過(guò)遍歷維度搜索。當(dāng)你搜索完了,嘗試分裂,你要評(píng)估這次分裂是好還是不好的時(shí)候?不能再使用Gini系數(shù)和信息熵了。因?yàn)槊恳粋€(gè)樣本跟每一個(gè)樣本之間的結(jié)果都不一樣。你想你原來(lái)是怎么算信息熵和Gini系數(shù)的?先看看我這葉子連接節(jié)點(diǎn)有幾類(lèi)數(shù)據(jù),把它們分別統(tǒng)計(jì)一下,算出一個(gè)數(shù)。而回歸問(wèn)題,它的y?lable有一樣的嗎?應(yīng)該說(shuō)沒(méi)有一樣的。這種情況下肯定不能用剛才那個(gè)Gini系數(shù)和熵來(lái)做了。那用什么呢,用mse來(lái)統(tǒng)計(jì)。
舉例比如下圖:
根節(jié)點(diǎn)里有100個(gè)數(shù)據(jù)我嘗試分裂。分裂出兩支來(lái), 一分支是有60個(gè)數(shù)據(jù)。另一支有40個(gè)數(shù)據(jù)。此時(shí)怎么評(píng)估這次的分裂效果呢?先計(jì)算這60條數(shù)據(jù)的y的均值。然后用這60條數(shù)據(jù)的每一個(gè)真實(shí)的y減去y的均值加平方求和除以60。就得出了這個(gè)葉子節(jié)點(diǎn)里邊的平均mse,能夠理解吧?那么右邊一樣,先是計(jì)算出40條y平均。用每一條y減去這個(gè)y的平均加平方求和,最后乘以各自的權(quán)重,還是要乘以一個(gè)1/60和1/40的。那么你多次嘗試分裂是不是就得到 或者你去想它會(huì)把y比較相近的一些節(jié)點(diǎn)分到同一個(gè)節(jié)點(diǎn)里邊去,對(duì)不對(duì)? 所以這就是回歸樹(shù)的計(jì)算流程。評(píng)估每次分裂效果的指標(biāo)我們叫它mse,它實(shí)際上是方差。就是一個(gè)集合里邊的每一個(gè)數(shù)減去均值平方通通加起來(lái)再除以數(shù)目本身,假如有十個(gè)數(shù),求這10個(gè)數(shù)的方差,首先要求出它的均值μ,用每一個(gè)數(shù)減去μ的差的平方,再相加,除一個(gè)1/10。這就是這個(gè)集合的方差。方差是一個(gè)統(tǒng)計(jì)學(xué)的指標(biāo),它描述的是什么?是這一組數(shù)據(jù)的離散程度。你方差越大代表這個(gè)數(shù)據(jù)里邊天差地別,對(duì)嗎?天南海北。方差越小,代表這一組數(shù)據(jù)非常緊密。彼此之間都差不了多少。那我們既然要做回歸問(wèn)題,我最終希望落到這個(gè)葉子節(jié)點(diǎn)里邊的lable越近越好還是越遠(yuǎn)越好?那肯定是越近越好對(duì)吧。我分著分著,越分越近,越分越近,最后得到的葉子結(jié)點(diǎn)都是最近的那些落到同一個(gè)葉子節(jié)點(diǎn)。那未來(lái)預(yù)測(cè)的時(shí)候怎么辦?它落到某一個(gè)葉子節(jié)點(diǎn)了。這個(gè)葉子節(jié)點(diǎn)是不是不知道應(yīng)該給它輸出多少值啊?它會(huì)輸出多少呢?平均值。能夠理解嗎?也就是說(shuō)這個(gè)東西回歸分析做出來(lái)之后,它是鋸齒狀的。能夠理解嗎?鋸齒狀的一個(gè)回歸分析。例如下圖:
?
就是因?yàn)閤都落在同一個(gè)葉子節(jié)點(diǎn)里邊輸出一個(gè)均值。而不象參數(shù)型模型了,按理來(lái)說(shuō),你只要變一點(diǎn)兒,那么y的結(jié)果多多少少都會(huì)變一點(diǎn)兒。而這個(gè)你的x只要變了一點(diǎn)兒就會(huì)影響到你最終落到那一個(gè)葉子節(jié)點(diǎn)。這樣你給的輸出是不是就都是一樣的了。所以對(duì)于回歸樹(shù)來(lái)說(shuō)還是那四個(gè)問(wèn)題。
一、它分幾支,我們剛才看了這個(gè)數(shù)分兩支,對(duì)不對(duì)?
二、它怎么判斷分裂條件。從原來(lái)的Gini系數(shù)變成了方差。或者說(shuō)變成了mse
三、它什么時(shí)候停止?還是那些預(yù)剪枝的過(guò)程。我們后面會(huì)講。
四、葉子節(jié)點(diǎn)怎么表達(dá)。從原來(lái)的投票算概率變成了算平均值。就是這么簡(jiǎn)單。
1-代碼詳解
我們來(lái)看下決策樹(shù)的應(yīng)用代碼:
import pandas as pd import numpy as np from sklearn.datasets import load_iris from sklearn.ensemble import RandomForestClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.tree import export_graphviz from sklearn.tree import DecisionTreeRegressor from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score import matplotlib.pyplot as plt import matplotlib as mpl #讀取iris數(shù)據(jù)集 iris = load_iris() #iris['data'] ['target'] # 讀取數(shù)據(jù)集 data = pd.DataFrame(iris.data)data.columns = iris.feature_names print(data.columns ) data['Species'] = load_iris().target print(data) print(data.shape) # #取數(shù)據(jù)幀的前四列(所有行)也就是X x = data.iloc[:, :4] # 花萼長(zhǎng)度和寬度 # x = data.iloc[:, :4] # 花萼長(zhǎng)度和寬度 #取數(shù)據(jù)幀的最后一列(所有行)也就y y = data.iloc[:, -1] # print(type(x),1) # y = pd.Categorical(data[4]).codes # print(x) # print(y)# #訓(xùn)練集和測(cè)試集的劃分 x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.75, random_state=42)tree_clf = DecisionTreeClassifier(max_depth=6, criterion='entropy') tree_clf.fit(x_train, y_train) y_test_hat = tree_clf.predict(x_test) print("acc score:", accuracy_score(y_test, y_test_hat)) ## export_graphviz( # tree_clf, # out_file="./iris_tree.dot", # feature_names=iris.feature_names[:2], # class_names=iris.target_names, # rounded=True, # filled=True # ) # # # ./dot -Tpng ~/PycharmProjects/mlstudy/bjsxt/iris_tree.dot -o ~/PycharmProjects/mlstudy/bjsxt/iris_tree.pngprint(tree_clf.predict_proba([[5, 1.5]])) print(tree_clf.predict([[5, 1.5]])) # RandomForestClassifier #生成一個(gè)數(shù)組 depth = np.arange(1, 15)#不同的深度對(duì)決策樹(shù)的影響 err_list = [] for d in depth:clf = DecisionTreeClassifier(criterion='entropy', max_depth=d)#預(yù)剪枝clf.fit(x_train, y_train)y_test_hat = clf.predict(x_test)result = (y_test_hat == y_test)# 生成一個(gè)長(zhǎng)度為驗(yàn)證集數(shù)量的數(shù)組,每一個(gè)元素是yhat和y是否相等的結(jié)果,print(list(result))if d == 1:print(result)#生成錯(cuò)誤率err = 1 - np.mean(result)print(100 * err)err_list.append(err)print(d, ' 錯(cuò)誤率:%.2f%%' % (100 * err)) plt.figure(facecolor='w') plt.plot(depth, err_list, 'ro-', lw=2) plt.xlabel('決策樹(shù)深度', fontsize=15) plt.ylabel('錯(cuò)誤率', fontsize=15) plt.title('決策樹(shù)深度和過(guò)擬合', fontsize=18) plt.grid(True) # plt.show()from sklearn import tree X = [[0, 0], [2, 2]] y = [0.5, 2.5] clf = tree.DecisionTreeRegressor()#回歸樹(shù) clf = clf.fit(X, y) clf.predict([[1, 1]]) # tree_reg = DecisionTreeRegressor(max_depth=2) # # tree_reg.fit(X, y)?
解釋下上面代碼:
1、from sklearn.datasets import load_iris????? iris = load_iris(),iris['data'] ['target']。這個(gè)iris里邊就包含了iris(data)和(target),這里邊有兩種調(diào)用它的方式。一種你可以寫(xiě)iris.Data,一種還有這種字典的方式,索引data,實(shí)際上sklearn把我們這兩種風(fēng)格的ATI都保留下來(lái)了。
2、我們?cè)谶@兒引入了一個(gè)工具叫pandas,我們之前簡(jiǎn)單的講了講numpy就是一個(gè)簡(jiǎn)單的玩數(shù)組的東西,而pandas就是對(duì)numpy簡(jiǎn)單的進(jìn)行了一個(gè)加強(qiáng)。原來(lái)的numpy是一個(gè)數(shù)組,pandas給每一列數(shù)組起了一個(gè)名字。比如說(shuō)data是數(shù)組。你想調(diào)用其中一個(gè)元素,用numoy來(lái)去你就必須寫(xiě)data[0,0],而pandas分別給行和列起了索引號(hào)。可以使用名稱(chēng)來(lái)更靈活的調(diào)用它,這是其一,也是最根本的區(qū)別。其次,pandas里邊集成了很多方面的數(shù)據(jù)操作的東西。這兩個(gè)就是一個(gè)簡(jiǎn)單的tool就是兩個(gè)簡(jiǎn)單的工具。你學(xué)Excel有多難學(xué)它就有多難能明所以它不是很復(fù)雜的東西。pandas里邊有一個(gè)對(duì)象叫dataframe實(shí)際上是叫數(shù)據(jù)幀,數(shù)據(jù)幀就是一個(gè)帶名稱(chēng)的二維數(shù)組。二維數(shù)組只有索引號(hào)。而dataframe加了一個(gè)名稱(chēng)。data = pd.DataFrame(iris.data),我們把這個(gè)iris里邊兒的data拿出來(lái),它是一個(gè)numpy數(shù)組。二維數(shù)組。data扔到dataframe中返回的一個(gè)什么東西呢?返回一個(gè)panda里邊叫df的對(duì)象。那df對(duì)象有兩個(gè)屬性。一個(gè)叫columns,是指它這個(gè)列的名稱(chēng)。一個(gè)叫index是指行的名稱(chēng)。
3、然后我們通過(guò)train_test_split 這個(gè)工具來(lái)劃分出驗(yàn)證集和測(cè)試集。然后我們新建一個(gè)對(duì)象叫做DecisionTreeClassifier,然后我們可以看到它實(shí)際上有兩個(gè)類(lèi)是決策樹(shù)的。DecisionTreeClassifier,DecisionTreeRegressor。分別是什么意思呢?不用我說(shuō)大家是不是已經(jīng)明白了?一個(gè)是用來(lái)做分類(lèi)的,一個(gè)是用來(lái)做回歸的。
4、我們看下DecisionTreeClassifier的超參數(shù)有哪些呢?
criterion,是拿什么東西來(lái)評(píng)價(jià)的標(biāo)準(zhǔn)。可以取值gini,Gini越高它越不純。也可以取值entropy評(píng)估的是信息增益。
splitter,取值Best是找到最好的那個(gè)分裂。取值random是找到最好的隨機(jī)分裂,也就是說(shuō)它隨機(jī)多少次之后,把隨機(jī)出來(lái)過(guò)的最好的結(jié)果給你。相當(dāng)于一個(gè)加速運(yùn)算的東西。相當(dāng)于找到了一個(gè)隨機(jī)出來(lái)的最優(yōu)解,有點(diǎn)像隨機(jī)梯度的意思。
max-depth,樹(shù)的最大深度。這個(gè)可以說(shuō)是我們最常用的預(yù)剪枝的操作手段。我們很多時(shí)候不去設(shè)置那些細(xì)枝末節(jié)的規(guī)則。僅僅設(shè)一下樹(shù)的最大深度,就是你分裂多少層就不要再繼續(xù)分裂了。我管你分的好分不好,你都不要再分裂了。
min_samples_split ,除了根結(jié)點(diǎn)和葉子結(jié)點(diǎn)其他中間的那些節(jié)點(diǎn)分裂一個(gè)所需要的最小的樣本量默認(rèn)是2。意思是這些節(jié)點(diǎn)要分裂所需的最小樣本數(shù)是2。
min_samples_leaf,葉節(jié)點(diǎn)最小樣本數(shù)。
min_weight_fraction_leaf,就是你這個(gè)葉子結(jié)點(diǎn)占總的比例有多少能成為葉子結(jié)點(diǎn),這個(gè)比較有意思。
max_features,就是說(shuō)在你尋找最佳切割點(diǎn)的時(shí)候要不要考慮所有的維度咱們本來(lái)是不是遍歷所有的維度?現(xiàn)在改成隨機(jī)取幾個(gè)維度遍歷。不取全了,能明白我的意思嗎?因?yàn)樗至押芏鄬?#xff0c;雖然第一層沒(méi)有考慮到這個(gè)維度。第二層的時(shí)候有可能就考慮到了,如果是default=none那么如果是none什么意思啊?全部的維度都要進(jìn)來(lái)去考慮如果你是int那么是什么意思呢?你傳一個(gè)整形進(jìn)來(lái)。就是每次在尋找切割的時(shí)候就隨機(jī)的找到。你比如說(shuō)乘以六。那么它就隨機(jī)找的六個(gè)維度去考慮,尋找最佳切割點(diǎn)。那這樣就肯定會(huì)變的不準(zhǔn)了,但會(huì)變得更快了。然后如果你傳一個(gè)浮點(diǎn)數(shù)過(guò)來(lái)那么實(shí)際上是百分比。你比如說(shuō)傳一個(gè)0.6。就是你每一次分裂的時(shí)候,就隨機(jī)挑選出60%的維度出來(lái),來(lái)尋找最佳切割點(diǎn),如果是auto,是開(kāi)個(gè)根號(hào)。比如說(shuō)你有100個(gè)維度。我就給你整十個(gè)緯度。能夠理解嗎?sqrt也是開(kāi)根號(hào)。Log2是取個(gè)log2然后再取,默認(rèn)的通常是就選none,有多少我就考慮多少。
max_leaf_nodes ,最多的葉子節(jié)點(diǎn)也是,如果葉子節(jié)點(diǎn)夠多了,你就不用再分裂了。
min_impurity_decrease ,我們的目的是gini系數(shù)必須得變小,我才讓你分裂。你原來(lái)的分裂越大,當(dāng)傳入一個(gè)float進(jìn)來(lái),必須要gini系數(shù)必須要縮小多少才能進(jìn)行此次分裂。
class-weigh,我們可以看到所有的函數(shù),分類(lèi)器也好,回歸器也好,都會(huì)有這個(gè)參數(shù)。class-weight代表什么呢?代表每類(lèi)樣本,你到底有多么看重它?它的目的是將不同的類(lèi)別映射為不同的權(quán)值,該參數(shù)用來(lái)在訓(xùn)練過(guò)程中調(diào)整損失函數(shù)(只能用于訓(xùn)練)。該參數(shù)在處理非平衡的訓(xùn)練數(shù)據(jù)(某些類(lèi)的訓(xùn)練樣本數(shù)很少)時(shí),可以使得損失函數(shù)對(duì)樣本數(shù)不足的數(shù)據(jù)更加關(guān)注。
5、我們創(chuàng)造一個(gè)這個(gè)DecisionTreeClassifier,然后輸出acc?score,然后輸出我們?cè)衮?yàn)證集上的準(zhǔn)確度,達(dá)到了97%,能看到嗎?比之前咱們的邏輯回歸,訓(xùn)練及效果要好不少。
6、for d in depth,以及下面的代碼大致意思是,我把樹(shù)的深度從一到15遍歷了一遍。然后分別畫(huà)出這15棵樹(shù)到底錯(cuò)誤率是多少。訓(xùn)練15個(gè)模型,我們可以看,隨著樹(shù)的深度增加,在4的時(shí)候驗(yàn)證集錯(cuò)誤率最低,但是后來(lái)隨著深度的增加,反倒又上升了。這就有一點(diǎn)點(diǎn)過(guò)擬合的意思,但在咱們這個(gè)數(shù)據(jù)集里很難形成過(guò)擬合。因?yàn)榭偣膊?50條數(shù)據(jù)。但是這個(gè)東西你可以看到,不是說(shuō)樹(shù)越深在驗(yàn)證集上效果就表現(xiàn)得越好。
下一節(jié)里面我們會(huì)講解決策樹(shù)的另一個(gè)問(wèn)題即什么時(shí)候停止的問(wèn)題。
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/LHWorldBlog/p/10880435.html
總結(jié)
以上是生活随笔為你收集整理的大白话5分钟带你走进人工智能-第二十六节决策树系列之Cart回归树及其参数(5)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: git移除某文件夹的版本控制
- 下一篇: SOA简介