主頁 > 後端開發 > 【機器學習15】決策樹模型詳解

【機器學習15】決策樹模型詳解

2020-09-21 12:32:19 後端開發

決策樹演算法

  • 前言
  • 一、決策樹的概述
  • 二、熵的作用
  • 三、決策樹構造實體
  • 四、資訊增益率和gini系數
  • 五、剪枝方法
  • 六、分類、回歸任務
  • 七、樹模型的可視化展示
  • 八、決策邊界展示分析
  • 九、決策樹預剪枝常用引數
  • 十、回歸樹模型
  • 總結

手動反爬蟲: 原博地址

 知識梳理不易,請尊重勞動成果,文章僅發布在CSDN網站上,在其他網站看到該博文均屬于未經作者授權的惡意爬取資訊

如若轉載,請標明出處,謝謝!

前言

隨著人工智能的不斷發展,機器學習這門技術也越來越重要,很多人都開啟了學習機器學習,本文就介紹了機器學習的決策樹的詳細內容,

一、決策樹的概述

決策樹是一種樹形結構,其中每個內部節點表示一個屬性上的測驗,每個分支代表一個測驗輸出,每個葉子節點代表一種類別,

樹的組成:(如下圖示,來源百度,只做結構演示說明)
根節點:第一個選擇點
非葉子結點與分支:中間程序
葉子節點:最終的決策結果
在這里插入圖片描述

兩大特征:從根節點開始一步步走到葉子節點(決策的程序)
所以的資料最終都會落到葉子節點,既可以做分類也可以做回歸

實作決策樹的流程,下面以一個簡單的一家人是否愛玩游戲進行劃分,如下
在這里插入圖片描述
將一家人看做為是一份資料,輸入到決策樹中,首先會進行年齡的判斷是否大于15歲(人為主觀認定的數值),如果大于15,就判斷為有較小可能性玩游戲,小于或等于15歲則認為有較大的可能性玩游戲,然后再進行下一步細分,判斷性別,如果是男生則認為有較大的可能性玩游戲,如果為女生則為較小的可能性喜歡玩游戲,

這就是一個簡單的決策樹的程序,有點像最初python學習時的進行if-else成績好壞等級分類的程式,但是,決策樹這里的分類的先后順序通常是不可以調換的,比如這里為什么要把年齡的判斷放在性別判斷前邊,就是因為希望第一次決策判斷就能實作大部分資料的篩選,盡可能的都做對了,然后再進行下一步,進而實作對上一步存在偏差資料的微調,因此根節點的重要性可想而知,其要實作對資料樣本大致的判斷,篩選出較為精確的資料,可以對比籃球比賽,當然是先上首發陣容,其次在考慮替補,針對于短板的地方進行補充,

那么問題就來了?(根節點如何選擇)—— 憑什么先按照年齡進行劃分,或者說憑什么認為他們是首發嗎?

判斷的依據是啥???接下來呢?次根節點又如何進行切分呢???

二、熵的作用

目標:通過一種衡量標準,來計算通過不同特征進行分支選擇后的分類情況,找出來最好的那個當成根節點,以此類推,

衡量標準-熵:熵是表示隨機變數不確定性的度量(解釋:說人話就是物體內部的混亂程度,比如義務雜貨市場里面什么都有那肯定混亂呀,專賣店里面只賣一個牌子的那就穩定多啦)

舉個例子:如下,A中決策分類完成后一側是有三個三角二個圓,另一側是兩個三角一個圓,而B中決策分類后是一側是三角一側是圓,顯然是B方案的決策判斷更靠譜一些,用熵進行解釋就是熵值越小(混亂程度越低),決策的效果越好

在這里插入圖片描述
有些時候是可以憑借的肉眼進行觀察的,但是大部分的決策結果并不能僅僅通過人為的評判,而需要一個量化的評判標準,于是就有了判斷公式: H ( X ) = ? ∑ p i ? l o g ( p i ) , i = 1 , 2 , . . . , n H(X)=- ∑ p_{i}* log(p_{i}), i=1,2, ... , n H(X)=?pi??log(pi?),i=1,2,...,n

這里以上面的例子進行公式解讀,都只單看左側的分類結果,對于B中的,只有三角,也就是一個分類結果, p i p_{i} pi?即為取值概率,這里就為100%,再結合一下log函式,其值在[0,1]之間是遞增的,那么前面加上一個負號就是遞減,因此這個B右側分類結果帶入計算公式值就是0,而0又是這個公式值中的最小值,再看A中左側的分類結果,由于存在著兩種情況,因此公式中就出現了累加,分別計算兩種結果的熵值情況,最后匯總,其值必然是大于0的,故A中的類別較多,熵值也就大了不少,B中的類別較為穩定(那么在分類任務重我們希望通過節點分支后資料類別的熵值大還是小呢?)

其實都不是,在分類之前資料有一個熵值,在采用決策樹之后也會有熵值, 還拿A舉例,最初的狀態五個三角三個圓(對應一個熵值1),經過決策之后形成左側三個三角兩個圓(對應熵值2)和右側的兩個三角一個圓(對應熵值3),如果最后的熵值2+熵值3 < 熵值1,那么就可以判定這次分類較好,比原來有進步,也就是通過對位元值(不確定性)減少的程度判斷此次決策判斷的好壞,不是只看分類后熵值的大小,而是要看決策前后熵值變化的情況,

為了方便記憶,于是有了 資訊增益 :表示特征X使得類Y的不確定性減少的程度,(分類后的專一性,希望分類后的結果是同類在一起,比如上面希望把三角形分在一塊,圓形分在一塊)

三、決策樹構造實體

這里使用官網提供的示例資料進行講解,資料為14天打球的情況(實際的情況);特征為4種環境變化( x i x_{i} xi?);最后的目標是希望構建決策樹實作最后是否打球的預測(yes|no),資料如下

x 1 : x_{1}: x1?: outlook
x 2 : x_{2}: x2?: temperature
x 3 : x_{3}: x3?: humidity
x 4 : x_{4}: x4?: windy

p l a y : play: play: yes|no

在這里插入圖片描述
由資料可知共有4種特征,因此在進行決策樹構建的時候根節點的選擇就有4種情況,如下,那么就回到最初的問題上面了,到底哪個作為根節點呢?是否4種劃分方式均可以呢?因此 資訊增益 就要正式的出場露面了
在這里插入圖片描述
由于是要判斷決策前后的熵的變化,首先確定一下在歷史資料中(14天)有9天打球,5天不打球,所以此時的熵應為(一般log函式的底取2,要求計算的時候統一底數即可): ? 9 14 ? l o g 2 9 14 ? 5 14 ? l o g 2 5 14 = 0.940 - \frac{9}{14}*log_{2}\frac{9}{14} - \frac{5}{14}*log_{2} \frac{5}{14} = 0.940 ?149??log2?149??145??log2?145?=0.940

先從第一個特征下手,計算決策樹分類后的熵值的變化,還是使用公式進行計算

Outlook = sunny時,熵值為0.971 ( ? 2 5 ? l o g 2 2 5 ? 3 5 ? l o g 2 3 5 = 0.971 - \frac{2}{5}*log_{2}\frac{2}{5} - \frac{3}{5}*log_{2} \frac{3}{5} = 0.971 ?52??log2?52??53??log2?53?=0.971
Outlook = overcast時,熵值為0
Outlook = rainy時,熵值為0.971( ? 3 5 ? l o g 2 3 5 ? 2 5 ? l o g 2 2 5 = 0.971 - \frac{3}{5}*log_{2}\frac{3}{5} - \frac{2}{5}*log_{2} \frac{2}{5} = 0.971 ?53??log2?53??52??log2?52?=0.971

注意:直接將計算得到的結果和上面計算出初始的結果相比較嗎? (當然不是,outlook取到sunny,overcast,rainy是有不同的概率的,因此最后的計算結果要考慮這個情況)

最終的熵值計算就為: 5 14 ? 0.971 + 0 + 5 14 ? 0.971 = 0.693 \frac{5}{14}*0.971 + 0 + \frac{5}{14}*0.971 = 0.693 145??0.971+0+145??0.971=0.693資訊增益:系統的熵值就由原始的0.940下降到了0.693,增益為
g a i n ( o u t l o o k ) = 0.247 gain(outlook) = 0.247 gain(outlook)=0.247依次類推,可以分別求出剩下三種特征分類的資訊增益如下:
g a i n ( t e m p e r a t u r e ) = 0.029 , g a i n ( h u m i d i t y ) = 0.152 , g a i n ( w i n d y ) = 0.048 gain(temperature) = 0.029, gain(humidity) = 0.152, gain(windy) = 0.048 gain(temperature)=0.029,gain(humidity)=0.152,gain(windy)=0.048最后我們選擇最大的那個就可以啦,相當于是遍歷了一遍特征,找出來了根節點(老大),然后在其余的中繼續通過資訊增益找子節點(老二)…,最終整個決策樹就構建完成了!

四、資訊增益率和gini系數

之前使用資訊增益進行判斷根節點有沒有什么問題,或者是這種方法是不是存在bug,有些問題是解決不了的???答案是當然有的,比如還是使用上面的14個人打球的資料,這里添加一個特征為打球的次數ID,分別為1,2,3,…,12,13,14,那么如果按照此特征進行決策判斷,如下
在這里插入圖片描述
由此特征進行決策判斷后的結果可以發現均為單個的分支,計算熵值的結果也就為0,這樣分類的結果資訊增益是最大的,說明這個特征是非常有用的,如果還是按照資訊增益來進行評判,樹模型就勢必會按照ID進行根節點的選擇,而實際上按照這個方式進行決策判斷并不可行,只看每次打球的ID并不能說這一天是不是會打球,

從上面的示例中可以發現資訊增益無法解決這種特征分類(類似ID)后結果特別特別多的情況,故就發展了另外的決策樹演算法叫做 資訊增益率gini系數

這里介紹一下構建決策樹中使用的演算法(至于前面的英文稱呼,知道是一種指代關系就可以了,比如說的資訊增益也可以使用ID3進行表示):

英文稱呼中文稱呼
ID3資訊增益 (本身是存在著問題的)
C4.5資訊增益率 (解決了ID3問題,考慮了自身熵)
CART使用gini系數作為衡量標準,計算公式: G i n i ( p ) = ∑ k = 1 K p k ( 1 ? p k ) = 1 ? ∑ k = 1 K p k 2 Gini(p) = \sum_{k=1}^{K}p_{k}(1-p_{k})=1- \sum_{k=1}^{K}p_{k}^{2} Gini(p)=k=1K?pk?(1?pk?)=1?k=1K?pk2?

還是以14個人打球的資料,講解一下資訊增益率,這里說考慮了自身熵,解決了ID3的問題是如何解決的呢?假設按照每次打球次數ID進行決策判斷,結果還是分為了14類,計算后的資訊增益為Q,從數值的大小上看一般是一個較小數值(0.940-0=0.940,絕對數值),但是對于其他資料特征分類的結果來看這個數值又是很大(0.940相較于其他的gain數值,對比數值),這時候的資訊增益率就為 Q ( ? 1 14 l o g 2 1 14 ) ? 14 \frac{Q}{(-\frac{1}{14}log_{2}\frac{1}{14})*14} (?141?log2?141?)?14Q?,從對比數值來看,這個Q是很大,但是考慮到自身的熵值,參考一下log函式的影像,分母的值就是更大了,由此這個公式計算的數值(資訊增益率)就會很小,也就解決了資訊增益中無法處理分類后資料類別特別多的情況

gini系數計算公式和熵的衡量標準類似,只是計算方式不相同,這里值越小代表這決策分類的效果越好,比如當p的累計值取1了,那么最后結果就為0,當p取值較小時,經過平方后就更小了,由此計算的結果也就趨近1了

資訊增益率 是對根據熵值進行判定方式的改進,而 gini系數 則是另起爐灶,有著自己的計算方式

五、剪枝方法

首先明確一下為啥會有剪枝的操作,對比一下日常生活中的種植園工修理花草樹木,如果不管,任其生長,最后結果很可能是雜草灌木叢生,決策樹過擬合風險很大,理論上是可以完全分得開全部的資料,也就是樹會野蠻生長,每個葉子節點都會有一個資料,然后就把所有的資料全部分類完成

過擬合通俗的講就是:你在日常的測驗做題或者考核的時候很好,但是一到大型的考試就不行了,這時候就存在邊看答案邊做題的現象,因此就可以把每道題都做對,就像決策樹一樣,可以無限的細分下去,滿足所有的分類結果,但是在最后預測的時候卻表現不好,故需要避免這種情況,也就需要進行剪枝,控制模型的復雜程度
在這里插入圖片描述

剪枝策略:預剪枝(邊建立決策樹邊進行剪枝的操作,比較實用)、后剪枝(當建立完成后再進行剪枝操作)

預剪枝方式:限制深度(比如指定到某一具體數值后不再進行分裂)、葉子節點個數、葉子節點樣本數、資訊增益量等
后剪枝方式:通過一定的衡量標準, C α ( T ) = C ( T ) + α ? ∣ T l e a f ∣ C_{\alpha}(T) = C(T) + \alpha*|T_{leaf}| Cα?(T)=C(T)+α?Tleaf?,葉子節點越多,損失越大

后剪枝的作業流程,比如選擇如下的節點,進行判斷其不分裂行不行? 不分裂的條件就是分裂之后的結果比分裂之前效果還要差勁,

在這里插入圖片描述

按照上面的計算公式,分裂之前 C α ( T ) = 0.444 ? 6 + 1 ? α C_{\alpha}(T) =0.444*6 + 1* \alpha Cα?(T)=0.444?6+1?α分裂之后就是兩個葉子節點之和相加 C α ( T ) = 3 ? 0 + 1 ? α + 0.444 ? 3 + 1 ? α = 0.444 ? 3 + 2 ? α C_{\alpha}(T) =3*0+1* \alpha + 0.444*3+1* \alpha=0.444*3 + 2* \alpha Cα?(T)=3?0+1?α+0.444?3+1?α=0.444?3+2?α最后就變成了比較這兩次取得的數值,值越大代表著損失越大,也就越不好,取值的大小是取決于我們給定的 α \alpha α值, α \alpha α值給出的越大,模型越會控制過擬合,值較小的時候是我們希望模型取得較好的結果,過不過擬合看的不是很重要

六、分類、回歸任務

樹模型做分類任務,某個葉子節點中的型別是由什么所決定的?還使用最初的圖示為例,樹模型是屬于有監督的演算法,資料在輸入之前就已經有標簽的,比如下面“-”代表不玩游戲,“+”代表玩游戲,那么右側紅框的分類結果中有三個“-”的資料,得到資料的眾數都是分類為“-”,所以之后如果有資料再分到此類別中,就都會被標記為“-”,故分類任務是有葉子節點中資料的眾數決定的,少數服從多數,加入某葉子節點中有10個“-”,2個“+”,則認定該葉子節點分類為“-”

回歸任務和分類任務的做法幾乎是一樣的,但是評估的方式是不一樣的,回歸是采用方差進行衡量的,比如將上面的五個人按照年齡進行判斷,是否為老年人,根究A方案,顯然其方差要原小于B方案中的方差,也就是人為A方案中劃分方式更為合理,那么既然是回歸問題也就避免不了資料取值,葉子節點中的數值計算的方式就為各個資料的平均數,那么接下來使用樹模型進行預測的時候,如果資料落入該葉子節點中數值即為此前計算的平均值,假如是A方案中的右側葉子節點,預測的結果數值就為(30+15+12) /3 =19
在這里插入圖片描述

七、樹模型的可視化展示

前期作業:下載可視乎的包:graphviz,并配置環境變數,檢驗前期作業完成的標識,在cmd命令列中輸入dot -version可以正常彈出如下資訊

在這里插入圖片描述

進入代碼書寫,首先匯入相關的庫,書寫環境為jupyter notebook

import warnings
warnings.filterwarnings('ignore')

import numpy as np
import os
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12

第二步就是進行樹模型的創建

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

iris = load_iris() #加載鳶尾花資料集
X = iris.data[:,2:] #這里先選擇兩個特征petal length and width(花瓣的長度和寬度)
y = iris.target #設定標簽

tree_clf = DecisionTreeClassifier(max_depth=2) #初始化樹模型并設定最大的深度為2
tree_clf.fit(X,y) #訓練樹模型

最后一步就是可視化展示

from sklearn.tree import export_graphviz #這個就是剛剛下載的軟體

export_graphviz(
    tree_clf, #第一個就是剛剛訓練好的樹模型
    out_file="iris_tree.dot", #這里指定輸出的檔案路徑和檔案名稱
    feature_names=iris.feature_names[2:], #畫圖中需要用到的特征名稱,上面選擇兩個,這里也是跟著一樣
    class_names=iris.target_names, #標簽設定
    rounded=True, #最后兩個默認即可
    filled=True
)

執行上面代碼后會在指定的檔案路徑下生成相應的檔案,然后,你可以使用graphviz包中的dot命令列工具將此.dot檔案轉換為各種格式,如PDF或PNG,下面這條命令列將.dot檔案轉換為.png影像檔案:dot -Tpng iris_tree.dot -o iris_tree.png

執行之后,就會在同路徑下生成指定格式的圖片
在這里插入圖片描述
圖片打開后如下,至此樹模型的可視化的展示也就完成了,其中白色分塊中都有五行代碼,第一行是指分類的條件,第二行是gini系數值,第三行是樣本資料量,第四行是原本三種類別的數量,最后一行是此次認定的資料分類結果
在這里插入圖片描述
如果還想要將生成的圖片在jupyter notebook中進行內嵌輸出,可以使用如下代碼

from IPython.display import Image
Image(filename='iris_tree.png',width=400,height=400)

八、決策邊界展示分析

概率計算:這里舉個例子,加入輸入的資料為花瓣長5厘米,寬1.5厘米的花, 相應的葉節點是深度為2的左節點,因此決策樹應輸出以下概率(對照著上面的可視化展示的樹模型圖)

Iris-Setosa 為 0%(0/54),
Iris-Versicolor 為 90.7%(49/54),
Iris-Virginica 為 9.3%(5/54),

使用代碼驗證一下

tree_clf.predict_proba([[5,1.5]])

輸出的結果為:

array([[0.        , 0.90740741, 0.09259259]])

如果是直接預測類別

tree_clf.predict([[5,1.5]])

輸出的結果為:

array([1]) #這里的1就代表是第二個類別,也就是Iris-Versicolor 

將所有的資料結果進行可視化展現

from matplotlib.colors import ListedColormap

def plot_decision_boundary(clf, X, y, axes=[0, 7.5, 0, 3], iris=True, legend=False, plot_training=True):
    x1s = np.linspace(axes[0], axes[1], 100)
    x2s = np.linspace(axes[2], axes[3], 100)
    x1, x2 = np.meshgrid(x1s, x2s)
    X_new = np.c_[x1.ravel(), x2.ravel()]
    y_pred = clf.predict(X_new).reshape(x1.shape)
    custom_cmap = ListedColormap(['#fafab0','#9898ff','#a0faa0'])
    plt.contourf(x1, x2, y_pred, alpha=0.3, cmap=custom_cmap)
    if not iris:
        custom_cmap2 = ListedColormap(['#7d7d58','#4c4c7f','#507d50'])
        plt.contour(x1, x2, y_pred, cmap=custom_cmap2, alpha=0.8)
    if plot_training:
        plt.plot(X[:, 0][y==0], X[:, 1][y==0], "yo", label="Iris-Setosa")
        plt.plot(X[:, 0][y==1], X[:, 1][y==1], "bs", label="Iris-Versicolor")
        plt.plot(X[:, 0][y==2], X[:, 1][y==2], "g^", label="Iris-Virginica")
        plt.axis(axes)
    if iris:
        plt.xlabel("Petal length", fontsize=14)
        plt.ylabel("Petal width", fontsize=14)
    else:
        plt.xlabel(r"$x_1$", fontsize=18)
        plt.ylabel(r"$x_2$", fontsize=18, rotation=0)
    if legend:
        plt.legend(loc="lower right", fontsize=14)

plt.figure(figsize=(8, 4))
plot_decision_boundary(tree_clf, X, y)

#下面這一部分是根據實際的決策樹的分類結果進行分類線的繪制
plt.plot([2.45, 2.45], [0, 3], "k-", linewidth=2)
plt.plot([2.45, 7.5], [1.75, 1.75], "k--", linewidth=2)
plt.plot([4.95, 4.95], [0, 1.75], "k:", linewidth=2)
plt.plot([4.85, 4.85], [1.75, 3], "k:", linewidth=2)
plt.text(1.40, 1.0, "Depth=0", fontsize=15)
plt.text(3.2, 1.80, "Depth=1", fontsize=13)
plt.text(4.05, 0.5, "(Depth=2)", fontsize=11)
plt.title('Decision Tree decision boundaries')

plt.show()

輸出的結果為:(關于網格和刻度方向的顯示問題可以通過修改matplotlib庫的組態檔修改)
在這里插入圖片描述

九、決策樹預剪枝常用引數

DecisionTreeClassifier類(sklearn的版本為0.23.1)還有一些其他引數類似地限制了決策樹的形狀:
min_samples_split(節點在分割之前必須具有的最小樣本數,默認為2),
min_samples_leaf(葉子節點必須具有的最小樣本數,默認為1),
max_leaf_nodes(葉子節點的最大數量),
max_features(在每個節點處評估用于拆分的最大特征數,一般不限制),
max_depth(樹最大的深度)

比如進行兩個樹模型不同引數的對比

from sklearn.datasets import make_moons
X,y = make_moons(n_samples=100,noise=0.25,random_state=53)

tree_clf1 = DecisionTreeClassifier(random_state=42)
tree_clf2 = DecisionTreeClassifier(min_samples_leaf=4,random_state=42) #就只有一個引數不同,進行對比
tree_clf1.fit(X,y)
tree_clf2.fit(X,y)

plt.figure(figsize=(12,4))
plt.subplot(121)
plot_decision_boundary(tree_clf1,X,y,axes=[-1.5,2.5,-1,1.5],iris=False)
plt.title('No restrictions')

plt.subplot(122)
plot_decision_boundary(tree_clf2,X,y,axes=[-1.5,2.5,-1,1.5],iris=False)
plt.title('min_samples_leaf=4')

輸出的結果為:(可以發現不做任何限制的時候,模型過擬合了,而添加葉子節點最小樣本數引數后,模型變得更加可靠,也可以測驗一下其他的引數)
在這里插入圖片描述
樹模型對資料的敏感,比如將資料的旋轉45度,那么模型的決策邊界是會發生變化的

np.random.seed(6)
Xs = np.random.rand(100, 2) - 0.5
ys = (Xs[:, 0] > 0).astype(np.float32) * 2

angle = np.pi / 4
rotation_matrix = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]])
Xsr = Xs.dot(rotation_matrix)

tree_clf_s = DecisionTreeClassifier(random_state=42)
tree_clf_s.fit(Xs, ys)
tree_clf_sr = DecisionTreeClassifier(random_state=42)
tree_clf_sr.fit(Xsr, ys)

plt.figure(figsize=(11, 4))
#旋轉之前
plt.subplot(121)
plot_decision_boundary(tree_clf_s, Xs, ys, axes=[-0.7, 0.7, -0.7, 0.7], iris=False)
plt.title('Sensitivity to training set rotation')  

#旋轉之后
plt.subplot(122)
plot_decision_boundary(tree_clf_sr, Xsr, ys, axes=[-0.7, 0.7, -0.7, 0.7], iris=False)
plt.title('Sensitivity to training set rotation')

plt.show()

輸出的結果為:(切記樹模型對資料是十分敏感的)
在這里插入圖片描述

十、回歸樹模型

回歸任務,就像前文中介紹的一樣,回歸和分類做法幾乎是一樣的,但是評估的方式是不一樣的,分類通過可視化的樹模型中可以看出是采用gini系數,而回歸任務就是使用方差的平均數(mse:mean squared error)

#設定資料
np.random.seed(42)
m=200
X=np.random.rand(m,1)
y = 4*(X-0.5)**2
y = y + np.random.randn(m,1)/10

#訓練模型
from sklearn.tree import DecisionTreeRegressor
tree_reg = DecisionTreeRegressor(max_depth=2)
tree_reg.fit(X,y)

#可視化模型
export_graphviz(
        tree_reg,
        out_file=("regression_tree.dot"),
        feature_names=["x1"],
        rounded=True,
        filled=True
    )
    
#notebook中顯示
# 你的第二個決策樹長這樣
from IPython.display import Image
Image(filename="regression_tree.png",width=400,height=400,)

輸出的結果為:

在這里插入圖片描述
然后對比一下樹的深度對模型的影響,通過可視化的圖形展示

from sklearn.tree import DecisionTreeRegressor

tree_reg1 = DecisionTreeRegressor(random_state=42, max_depth=2)
tree_reg2 = DecisionTreeRegressor(random_state=42, max_depth=3)
tree_reg1.fit(X, y)
tree_reg2.fit(X, y)

def plot_regression_predictions(tree_reg, X, y, axes=[0, 1, -0.2, 1], ylabel="$y$"):
    x1 = np.linspace(axes[0], axes[1], 500).reshape(-1, 1)
    y_pred = tree_reg.predict(x1)
    plt.axis(axes)
    plt.xlabel("$x_1$", fontsize=18)
    if ylabel:
        plt.ylabel(ylabel, fontsize=18, rotation=0)
    plt.plot(X, y, "b.")
    plt.plot(x1, y_pred, "r.-", linewidth=2, label=r"$\hat{y}$")

plt.figure(figsize=(11, 4))
plt.subplot(121)

plot_regression_predictions(tree_reg1, X, y)
for split, style in ((0.1973, "k-"), (0.0917, "k--"), (0.7718, "k--")):
    plt.plot([split, split], [-0.2, 1], style, linewidth=2)
plt.text(0.21, 0.65, "Depth=0", fontsize=15)
plt.text(0.01, 0.2, "Depth=1", fontsize=13)
plt.text(0.65, 0.8, "Depth=1", fontsize=13)
plt.legend(loc="upper center", fontsize=18)
plt.title("max_depth=2", fontsize=14)

plt.subplot(122)

plot_regression_predictions(tree_reg2, X, y, ylabel=None)
for split, style in ((0.1973, "k-"), (0.0917, "k--"), (0.7718, "k--")):
    plt.plot([split, split], [-0.2, 1], style, linewidth=2)
for split in (0.0458, 0.1298, 0.2873, 0.9040):
    plt.plot([split, split], [-0.2, 1], "k:", linewidth=1)
plt.text(0.3, 0.5, "Depth=2", fontsize=13)
plt.title("max_depth=3", fontsize=14)

plt.show()

輸出的結果為:

在這里插入圖片描述
最后對比一下最小的葉子節點的樣本數量

tree_reg1 = DecisionTreeRegressor(random_state=42)
tree_reg2 = DecisionTreeRegressor(random_state=42, min_samples_leaf=10)
tree_reg1.fit(X, y)
tree_reg2.fit(X, y)

x1 = np.linspace(0, 1, 500).reshape(-1, 1)
y_pred1 = tree_reg1.predict(x1)
y_pred2 = tree_reg2.predict(x1)

plt.figure(figsize=(11, 4))

plt.subplot(121)
plt.plot(X, y, "b.")
plt.plot(x1, y_pred1, "r.-", linewidth=2, label=r"$\hat{y}$")
plt.axis([0, 1, -0.2, 1.1])
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", fontsize=18, rotation=0)
plt.legend(loc="upper center", fontsize=18)
plt.title("No restrictions", fontsize=14)

plt.subplot(122)
plt.plot(X, y, "b.")
plt.plot(x1, y_pred2, "r.-", linewidth=2, label=r"$\hat{y}$")
plt.axis([0, 1, -0.2, 1.1])
plt.xlabel("$x_1$", fontsize=18)
plt.title("min_samples_leaf={}".format(tree_reg2.min_samples_leaf), fontsize=14)

plt.show()

輸出的結果為:(可以看出不約束默認情況下,樹模型會盡量擬合所有的點,但是改變引數數值后,模型變得橫平豎直的,也可以設定其他的常用的引數玩一玩)
在這里插入圖片描述
至此關于回歸樹模型的介紹就完畢了,撒花??ヽ(°▽°)ノ?

總結

文章中沒有對決策樹的由來和歷史進行過多的講解,直接有日常的小例子入手引入決策樹模型,并層層遞進式的講解決策樹中涉及的知識點,然后通過代碼進行可視化的展示,并以圖示的方式對比不同引數對于樹模型的影響,最后要注意的是決策樹不僅可以做分類也可以做回歸任務

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/96999.html

標籤:java

上一篇:鴻蒙OS,運行第一個“hello world”

下一篇:hadoop-day02

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more