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