不管是在Kaggle這類競賽中,仍是商業環境,決策樹迴歸器都已是最經常使用的機器學習算法之一。決策樹可用於分類和迴歸問題。本文介紹了決策樹迴歸器算法以及一些高級話題。html
介紹
ios
重要術語算法
它是如何工做的?數組
如何爲決策樹拆分決策?bash
問答網絡
何時不用?dom
優勢和缺點機器學習
避免過分擬合的技巧函數
決策樹與隨機森林性能
Sklearn決策樹的超參數
基於樹的模型VS線性模型
決策樹模型的可視化
結論
參考
Photo by Todd Quackenbush / Unsplash-
決策樹能夠用如下要點歸納:
決策決策樹是使用一組二進制規則來計算目標值的預測模型
每一個個體樹都是一個簡單的模型,有分支,節點和葉子
在深刻研究以前,讓咱們看一下決策樹的基本術語:
根節點:它表明整個整體或樣本,並進一步拆分爲兩個或更多個同類集。
拆分:將節點劃分爲兩個或更多個子節點的過程。
決策節點:當子節點分裂成更多的子節點時,它被稱爲決策節點。
葉子/終端節點:不拆分的節點稱爲葉子或終端節點。
剪枝:刪除決策節點的子節點,此過程稱爲剪枝。能夠認爲是拆分的反過程。
分支/子樹:整個樹的子部分稱爲分支或子樹。
父節點和子節點:劃分出子節點的節點稱爲子節點的父節點,而子節點是父節點的子節點。
決策樹經過向數據提出一系列問題來實現估計值,每一個問題都會縮小可能值的範圍,直到模型足夠自信地進行單個預測。問題的順序及其內容由模型決定。此外,提出的問題都是真/假的形式。
這有點難以掌握,由於它不是人類天然思考的方式,也許顯示這種差別的最好方法是建立一個真正的決策樹。在上述問題中X1,X2是兩個特徵,它們容許咱們經過詢問真/假來對目標變量y進行預測。
對於每一個真/假的答案,都有單獨的分支。不管問題的答案如何,咱們最終都會實現一個預測(葉節點)。從頂部的根節點開始,而後在樹中繼續回答問題。因此給出任何一對X1,X2。
我應該提到的決策樹的一個方面是它實際是如何學習的(如何造成'問題'以及如何設置閾值)。做爲監督機器學習模型,決策樹學習將數據映射到訓練模型構建的輸出上。
在訓練期間,模型將擬合任何與問題域相關的歷史數據,以及咱們但願模型預測的真實值。該模型將學習數據和目標變量之間的關係。
在訓練階段以後,決策樹產生相似於上圖所示的樹,計算最佳問題以及要求的順序,以便可以進行最準確的估計。當咱們想要進行預測時,應該向模型提供相同的數據格式。預測將是基於訓練過的訓練數據集產生估計值。
制定拆分的策略會嚴重影響樹的準確性。對分類和迴歸樹來講決策標準不一樣。決策樹迴歸器一般使用均方偏差(MSE)來決定將節點分紅兩個或更多個子節點。
假設咱們正在作二叉樹,算法首先會選擇一個值,而後將數據拆分爲兩個子集。對於每一個子集,它將分別計算MSE。樹將會選擇具備最小MSE值的結果的值。
讓咱們來看一下Splitting如何決定決策樹迴歸器的更多細節。建立樹的第一步是建立第一個二元決策。你打算怎麼作?
咱們須要選擇一個變量和要拆分的值,以使兩個組儘量彼此不一樣。
對於每一個變量,對於該變量的可能值的每一個可能值,查看哪一個更好。
如何判斷它是否更好?取兩個新節點的加權平均值(mse * num_samples)。
那麼咱們如今有:
一個表示拆分的效果的數字,是兩組建立的平均平方偏差的加權平均值。
找到最佳拆分的方法,即嘗試每一個變量和該變量的每一個可能值,並查看哪一個變量和哪一個值爲咱們提供了最佳得分的劃分。
這是建立決策樹迴歸器的所有內容,而且當知足一些中止條件(由超參數定義)時將中止:
達到要求的限制時(例如max_depth)。
當你的葉子節點中只有一項(可能沒有進一步劃分,訓練的MSE將爲零,可是對其餘數據集可能會過分擬合 - 不是一個有用的模型)。
是否有劃分紅3組的狀況?
沒有必要在一個級別上進行屢次劃分,由於您能夠再進一步拆分它們。
它是如何進行預測的?
給定一個數據點,您能夠在整個樹中運行它,詢問真/假,直到它到達葉節點爲止。最終預測是該葉節點中因變量的值的平均值。
由於咱們嘗試了每一個變量和每一個變量可能的值來決策一個拆分。訓練的計算成本會很高嗎?
在這裏,咱們要記住,當今計算機的CPU性能是以千兆赫茲來衡量的,即每秒數十億個時鐘週期,它有多個核心,每一個核心都有一個稱爲單指令、多數據(SIMD)的東西,它能夠一次對每一個核心進行8次計算。此外,若是您使用的是GPU,那麼這個過程會更快,由於它的性能是以teraflops來衡量的,因此每秒要進行數萬億次浮點運算。因此,這就是設計算法的地方,僅僅是人類很難意識到,考慮到當今計算機的速度有多快,算法應該多麼愚蠢。總而言之,有至關多的操做,可是每秒數萬億次的速度幾乎注意不到。
每一個節點的MSE計算哪一個底層模型?
基礎模型只是數據點的平均值。對於初始根節點,咱們只是預測了全部訓練數據點的因變量平均值。另外一個可能的選擇是不用平均數來使用中位數,或者咱們甚至能夠運行一個線性迴歸模型。咱們能夠作不少事情,但在實踐中,平均值很是有效。它們確實存在在隨機森林模型中,其中葉節點是獨立的線性迴歸,但應用並不普遍。
給定相同的數據和超參數,深度爲n的DT將包含深度爲n-1的DT?
所以,若是咱們建立一個深度爲3的樹和另外一個咱們擺脫最大深度的樹,那麼沒有最大深度約束的樹將包含深度爲3的樹。這假設數據和超參數將是相同的而且沒有添加隨機性(更深的樹將包含不太深的樹)。
如前所述,若是提供給劃分預測的數據與訓練數據無關,決策樹將沒法作出準確的預測。讓咱們用一個例子來證實這個論點:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.tree import DecisionTreeRegressorx = np.linspace(0,1)y = x + np.random.uniform(-0.2,0.2,x.shape)plt.scatter(x,y)複製代碼
咱們如今要構建一個決策樹模型,這其實是一個時間序列問題。因此我打算將左側部分做爲訓練集。並將右側部分做爲咱們的驗證集。
# train, validation set splitx_trn, x_val = x[:40,None], x[40:,None]y_trn, y_val = y[:40,None], y[40:,None]# fit a modelm = DecisionTreeRegressor(max_depth=6).fit(x_trn, y_trn)複製代碼
請注意,決策樹迴歸器指望二維數組,而不是二維數組中的一維數組。
咱們如今繪製結果:
plt.scatter(x_val,m.predict(x_val),color='blue',label='Prediction') plt.scatter(x_val,y_val,color='red',label='Actual') plt.scatter(x_trn,m.predict(x_trn),color='blue') plt.scatter(x_trn,y_trn,color='red') plt.legend(loc='upper left')複製代碼
若是您不知道決策樹如何工做,那麼這將使模型無用。換句話說,決策樹和基於樹的模型一般沒法推斷出他們之前從未見過的任何類型的數據,特別是將來的時間段,由於它只是平均它已經看到的數據。
簡而言之,決策樹和基於樹的模型通常只作一個聰明的最鄰近法。
在這種問題中,任何基於樹的算法都沒有用,首選模型是神經網絡或線性迴歸模型。緣由是當你想要使用一個模型,而它有一個函數或者形狀,它能夠很好地進行外推。
決策樹的一個主要缺點是它們容易過分擬合。這就是爲何不多使用他們,而是使用其餘基於樹的模型,如隨機森林和XGBoost。
總之,決策樹和通用基於樹的模型是一種監督學習算法(具備預約義的目標變量),主要用於分類問題。如上所述,當且僅當目標變量位於訓練數據集中值的範圍內時,它們才用於迴歸問題。
優點
它可用於分類和迴歸問題有時間作的好一點。
易於理解,解釋,可視化。
在數據探索中頗有用:決策樹是識別最重要變量和兩個或多個變量之間關係的最快方法之一。藉助決策樹,咱們能夠建立新的變量/特徵,這些變量/特徵具備更好的預測目標變量的能力。
須要更少的數據準備:它不受異常值和缺失值的影響。
數據類型不是約束:它能夠處理數值和分類變量。
非參數方法:決策樹被認爲是非參數方法。這意味着決策樹沒有關於空間分佈和分類器結構的假設。
能夠捕獲非線性關係。
劣勢
過擬合:過擬合是決策樹模型最實際的難點之一。經過設置模型參數約束和剪枝(下面詳細討論)能夠解決這個問題。
不適合連續變量:在處理連續數值變量時,決策樹在對不一樣類別的變量進行分類時會丟失信息。
沒法推斷。
決策樹可能不穩定:數據的微小變化可能致使生成徹底不一樣的樹。這稱爲方差,須要經過bagging 和 boosting等方法下降。
沒法保證返回全局最優決策樹。這能夠經過訓練多個樹來彌補,其中特徵和樣本隨替換而隨機取樣。
一般,您可能會發現您的模型與數據過分匹配,這一般會在引入新數據時損害模型的性能。若是決策樹沒有限制集,它會在訓練集上給你一個零MSE,由於在更糟的狀況下,它最終會爲每次觀察生成一個葉子。所以,在訓練決策樹時,防止過分擬合很是重要,能夠經過如下方式進行:
設置樹大小的約束(微調超參數)
樹剪枝
使用隨機森林
讓咱們簡單地討論這些方面。
這能夠經過微調樹的一些超參數來完成。首先,讓咱們看一下決策樹的通常結構:
經過了解樹建模中使用的參數的做用,能夠幫助您在R&Python中更好地微調決策樹。
節點拆分的最小樣本
定義要考慮拆分的節點中所需的最小樣本數(或觀測值)。
用於控制過分擬合。較高的值會阻止模型學習與樹選擇的特定樣本高度特別的關係。
過高的值會致使欠擬合,所以應該當心微調。
終端節點的最小樣本(葉子)
定義終端節點或葉子中所需的最小樣本(或觀察值)。
用於控制過分擬合,相似於節點拆分的最小樣本。
過高的值會致使欠擬合,所以應該當心微調。
樹的最大深度(垂直深度)
用於控制過分擬合,由於更高的深度將使模型學習特定樣本的關係。
過高的值會致使過分擬合,所以應當心微調。
拆分須要考慮的最大特徵
搜索最佳拆分時要考慮的特徵數量。這些將是隨機選擇的。
根據經驗法則,特徵總數的平方根很是有效,但咱們應該檢查特徵總數的30-40%。
較高的值可能致使過分擬合,但取決於具體狀況。
如前所述,設置約束的技術是一種貪婪方法。換句話說,它將當即檢查最佳劃分並向前移動,直到達到指定的中止條件之一。
決策樹算法中出現的問題之一是最終樹的最佳大小。太大的樹存在過分擬合訓練數據的風險,而且很難推廣到新樣本。小樹可能沒法捕獲有關樣本空間的重要結構信息。可是,很難判斷樹算法什麼時候應該中止,由於沒法判斷添加單個額外節點是否會顯着減小錯誤。這個問題被稱爲地平線效應。一種常見的策略是擴展樹,直到每一個節點包含少許實例,而後使用剪枝來刪除不提供其餘信息的節點。
剪枝應該減少學習樹的大小,而不下降交叉驗證集測量的預測精度。在用於優化性能的測量中,有許多不一樣的剪枝技術。
最簡單的剪枝形式之一是減小錯誤剪枝。從葉子開始,每一個節點都用其平均值替換。若是MSE不受影響,則保留更改。雖然有點天真,但減小錯誤剪枝具備簡單和迅速的優勢。
彷佛沒有多少人真正花時間去剪枝決策樹或進行微調,而是選擇使用隨機森林迴歸器(決策樹集合),它比單個優化樹更不容易過分擬合,性能更好。
在隨機森林上使用決策樹的常見論點是,決策樹更容易解釋,您只需查看決策樹邏輯便可。然而,在一個隨機森林中,您不須要研究500個不一樣樹的決策樹邏輯。
同時,隨機森林其實是決策樹的集合,這使得算法對於實時預測來講緩慢且無效。通常來講,RF能夠快速訓練,可是一旦訓練開始就會很慢地建立預測。這是由於它必須對每棵樹進行預測,而後進行平均以建立最終預測。(解決方法能夠是同時使用不一樣樹的集羣)
更準確的預測須要更多的樹,這會致使模型變慢。在大多數實際應用中,隨機森林算法速度足夠快,但在某些狀況下,運行時性能是很重要的,因此會首選其餘方法。
最後,決策樹確實存在過分擬合問題,而隨機森林能夠防止過分擬合,從而在大多數狀況下獲得更好的預測。這是隨機森林迴歸模型事實的一個顯著優點,使其對許多數據科學家更具吸引力。
min_samples_leaf :int,float,optional(default = 1)
它是咱們上面討論的終端節點的最小樣本數。
若是是int,則將min_samples_leaf視爲最小數字。
若是是float,則min_samples_leaf是一個百分比,ceil(min_samples_leaf * n_samples)是每一個節點的最小樣本數。
min_samples_split:int,float,optional(default = 2)
它是咱們上面討論的節點拆分的最小樣本。
若是是int,則將min_samples_split視爲最小數字。
若是是float,則min_samples_split是一個百分比,ceil(min_samples_split * n_samples)是每一個拆分的最小樣本數。
max_features:int,float,string或None,optional(default =「auto」)
尋找最佳拆分時要考慮的特徵數量:
若是是int,則在每次拆分時考慮max_features特徵。 - 若是是浮點數,則max_features是百分比,而且在每次拆分時都會考慮int(max_features * n_features)要素。
若是是「auto」,則max_features = sqrt(n_features)。
若是是「sqrt」,則max_features = sqrt(n_features)(與「auto」相同)。
若是是「log2」,則max_features = log2(n_features)。
若是爲None,則max_features = n_features。
max_depth :整數或無,可選(默認=無)
樹的最大深度。若是爲None,則擴展節點直到全部葉子都是純的或直到全部葉子包含少於min_samples_split樣本。
實際上,您可使用任何算法。這取決於您要解決的問題類型。讓咱們看一些關鍵因素,它們將幫助您決定使用哪一種算法:
若是依賴變量和自變量之間的關係用線性模型很好地逼近,線性迴歸將優於基於樹的模型。
若是因變量和自變量之間存在高度的非線性和複雜關係,樹模型將優於經典的迴歸方法。
若是你須要創建一個易於向人們解釋的模型,決策樹模型老是比線性模型作得更好。決策樹模型比線性迴歸更容易解釋!
讓咱們用一個例子證實咱們在第1點和第2點的論證:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.tree import DecisionTreeRegressorfrom sklearn.linear_model import LinearRegressionplt.figure(figsize=(20,10))x = np.linspace(0,2,10000)y = 1+ 3*xplt.scatter(x,y)複製代碼
咱們如今要構建決策樹和線性模型。咱們指望線性模型完美擬合,由於目標變量與特徵x線性相關。所以,我將對數據進行無序處理,將70%視爲訓練集,將30%視爲驗證。
idxs_train = sorted(np.random.permutation(len(x))[:int(0.7*len(x))])idx_test = [i for i in range(0,len(x)) if i not in idxs_train]# train, validation set splitx_trn, x_val = x[idxs_train,None], x[idx_test,None]y_trn, y_val = y[idxs_train,None], y[idx_test,None]# fit a modeldt = DecisionTreeRegressor(max_depth=3).fit(x_trn, y_trn)l = LinearRegression().fit(x_trn, y_trn)複製代碼
請注意,兩個模型都指望二維數組。咱們如今繪製結果:
plt.figure(figsize=(20,10))plt.scatter(x,dt.predict(x[:,None]),color='blue',label='Prediction DT')plt.scatter(x,l.predict(x[:,None]),color='green',label='Prediction Linear')plt.scatter(x,y,color='red',label='Actual')plt.legend(loc='upper left')複製代碼
在某種程度上,決策樹試圖適應 staircase。顯然,在這種狀況下,線性模型運行得很好,但在目標變量與輸入特徵不線性相關的其餘狀況下,DT將是更好的選擇,由於它可以捕獲非線性。另請參閱如下SciKit學習文檔中的另外一個示例:
可視化決策樹很是簡單。讓咱們繪製上面訓練過的決策樹。
首先,咱們須要導入一些額外的庫:
from sklearn.tree import export_graphvizimport IPython, graphviz, re, math複製代碼
而後咱們能夠簡單地繪製決策樹,以下所示:
def draw_tree(t, col_names, size=9, ratio=0.5, precision=3): """ Draws a representation of a random forest in IPython. Parameters: ----------- t: The tree you wish to draw df: The data used to train the tree. This is used to get the names of the features. """ s=export_graphviz(t, out_file=None, feature_names=col_names, filled=True, special_characters=True, rotate=True, precision=precision) IPython.display.display(graphviz.Source(re.sub('Tree {', f'Tree {{ size={size}; ratio={ratio}',s)))col_names =['X']draw_tree(dt, col_names, precision=3)複製代碼
如您所見,咱們正在獲取數據的子集,並決定進一步劃分子集的最佳方式。咱們的初始子集是整個數據集,咱們根據規則對其進行拆分X<=1.001。而後,對於每一個子集,咱們執行額外的拆分,直到咱們可以正確地預測目標變量,同時遵照約束max_depth=3。
決策樹是最普遍使用的機器學習模型之一,由於它們能夠很好地處理噪聲或丟失的數據,而且能夠很容易地進行整合以造成更強大的預測器。此外,您能夠直接看到模型的學習邏輯,這意味着它是一個很是受歡迎的模型,適用於模型可解釋性很重要的領域。
感謝閱讀,我期待着聽到你的問題,敬請關注並快樂機器學習。
https://scikit-learn.org/stable/modules/tree.html
https://en.wikipedia.org/wiki/Decision_tree_pruning
https://stackoverflow.com/questions/49428469/pruning-decision-trees