機器學習之決策樹——學習總結
阿新 • • 發佈:2019-01-22
決策樹學習總結
機器學習的應用越來越廣泛,特別是在資料分析領域。本文是我學習決策樹演算法的一些總結。
機器學習簡介
機器學習 (Machine Learning) 是近 20 多年興起的一門多領域交叉學科,涉及概率論、統計學、逼近論、凸分析、演算法複雜度理論等多門學科。簡而言之,機器學習是通過學習老知識(訓練樣本),得出自己的認知(模型),去預測未知的結果。
- 學習方式
- 監督式學習
- 從給定的訓練資料集中學習出一個函式,當新的資料到來時,可以根據此函式預測結果。訓練資料集中的目標由人標註的。常見的演算法有迴歸分析和統計分類
- 非監督式學習
- 與監督式學習相比,訓練集沒有人為標註的結果,常見的演算法有聚類
- 半監督式學習
- 訓練集部分被標識,部分沒有被標識。常見的演算法有SVM
- 強化學習
- 輸入資料作為模型的反饋,模型對此作出調整。常見的演算法有時間差學習
- 監督式學習
- 機器學習演算法分類
- 決策樹演算法
- 根據資料屬性,採用樹狀結構建立決策模型。常用來解決分類和迴歸問題。
- 常見演算法:CART(Classification And Regression Tree),ID3,C4.5,隨機森林等
- 迴歸演算法
- 對連續值預測,如邏輯迴歸LR等
- 分類演算法
- 對離散值預測,事前已經知道分類,如k-近鄰演算法
- 聚類演算法
- 對離散值預測,事前對分類未知,如k-means演算法
- 神經網路
- 模擬生物神經網路,可以用來解決分類和迴歸問題
- 感知器神經網路(Perceptron Neural Network) ,反向傳遞(Back Propagation)和深度學習(DL)
- 整合演算法
- 整合幾種學習模型進行學習,將最終預測結果進行彙總
- Boosting、Bagging、AdaBoost、隨機森林 (Random Forest) 等
- 決策樹演算法
決策樹演算法
初識決策樹
決策樹演算法是藉助於樹的分支結構實現分類。以相親約會決策為例,下圖是建立好的決策樹模型,資料的屬性有4個:年齡、長相、收入、是否公務員,根據此模型,可以得到最終是見或者不見。
這樣,我們對決策樹有個初步認識:- 葉子節點:存放決策結果
- 非葉子節點:特徵屬性,及其對應輸出,按照輸出選擇分支
- 決策過程:從根節點出發,根據資料的各個屬性,計算結果,選擇對應的輸出分支,直到到達葉子節點,得到結果
構建決策樹
通過上述例子,構建過程的關鍵步驟是選擇分裂屬性
,即年齡、長相、收入、公務員這4個屬性的選擇先後次序。分裂屬性
是在某個節點處按照某一特徵屬性的不同劃分構造不同的分支,其目標是讓各個分裂子集儘可能的“純”,即每個子集儘量都屬於同一分類項。分裂屬性分3種情況:- 屬性是離散值且不要求生成二叉樹
- 屬性的每個值作為一個分支
- 屬性是離散值且要求生成二叉樹
- 按照“屬於”和“不屬於”分成2個分支
- 屬性是連續值
- 確定一個分裂點split_point,按照>split_point和<=split_point生成2個分支
注意,決策樹使用自頂向下遞迴分治法,並採用不回溯的
貪心策略
。分裂屬性
的選擇演算法很多,這裡介紹3種常用的演算法:資訊增益(Information gain)、增益比率(gain ratio)、基尼指數(Gini index)- 屬性是離散值且不要求生成二叉樹
- 資訊增益(Information Gain)
基於香濃的資訊理論,資訊熵表示不確定度,均勻分佈時,不確定度最大,此時熵就最大。當選擇某個特徵對資料集進行分類時,資料集分類後的資訊熵會比分類前的小,其差值即為資訊增益
。資訊增益可以衡量某個特徵對分類結果的影響大小,越大越好。
- 典型演算法:ID3
- 資料集D中,有m個類別,\( p_i \)表示D中屬於類別i的概率,此資料集的資訊熵定義為:
Info(D)=−∑_i=1mp_ilog_2(p_i) - 以屬性R作為分裂屬性,R有k個不同的取值,將資料D劃分成k組,按R分裂後的資料集的資訊熵為:
Info_R(D)=∑_j=1k|D_j||D|×Info(D_j) - 資訊增益,即為劃分前後,資訊熵之差:
Gain(R)=Info(D)−InfoR(D) - 在每層分裂時,選擇使得Gain(R)最大的屬性作為分裂屬性
- 缺點:此公式偏向資料量多的屬性,如果樣本分佈不均,則會導致
過擬合
。假如上述例子中包括人名屬性,每個人名均不同,顯然以此屬性作為劃分,資訊增益最高,但是,很明顯,以此屬性作為劃分毫無意義
- 資訊增益比率(Gain Ratio)
針對上述方法問題,此方法引入分裂資訊SplitInfo_R(D)=−∑_j=1k|D_j|D×log_2(|D_j|D))
- 典型演算法:C4.5
- 資訊增益比率定義為:
GainRatio(R)=Gain(R)SplitInfo_R(D) - 缺點:\( SplitInfo_R(D) \)可能取值為0,此時無意義;當期趨於0時,GainRatio也不可信,改進措施是在分母加一個平滑,這裡加所有分裂資訊的平均值\( GainRatio(R)=\frac{Gain(R)}{\overline{SplitInfo(D)}+SplitInfo_R(D)} \)
- 基尼指數(Gini index)
另外一種資料不純度的度量方法,定義為:Gini(D)=1−∑_i=1mp_i2
其中,m為資料集D中類別的個數,\( p_i \)表示D中屬於類別i的概率,如果所有記錄都屬於同一個類中,則P1=1,Gini(D)=0。
- 典型演算法:CART
- 以屬性R作為分裂屬性,R有k個不同的取值,將資料D劃分成k組,按R分裂後的資料集的基尼指數為:
Gini_R(D)=∑_i=1k|D_i||D|Gini(D_i) - 計算劃分前後基尼指數之差
△Gini(R)=Gini(D)−Gini_R(D) 計算Gini(R)增量最大的屬性作為最佳分裂屬性。
spark中實現
具體程式碼參考spark原始碼包下的org.apache.spark.examples.mllib.DecisionTreeClassificationExample
,DecisionTree.trainClassifier
的實現步驟,核心程式碼在RandomForest.run()方法
- 根據輸入資料,構建RDD[LabeledPoint],儲存label和features
- 根據資料,構建metaData,包括feature個數、樣本資料條數、分類個數等
val metadata =
DecisionTreeMetadata.buildMetadata(retaggedInput, strategy, numTrees, featureSubsetStrategy)
- 計算每個feature的可能劃分點split1、split2。。。split(n-1)劃分成n個bin
val splits = findSplits(retaggedInput, metadata, seed)
- 連續值:取樣資料,根據不同值個數和步長進行劃分
- 離散:
- unorder:特徵種類為binsNum(分類個數不大,且為多分類)
- order:迴歸、二分類、多分類且數量很大,都使用二分類
- 根據feature的split,計算每條資料在每個feature下所在的bin,生成新的RDD[TreePoint(Label, featuresBin[])]
val treeInput = TreePoint.convertToTreeRDD(retaggedInput, splits, metadata)
- bagging取樣(示例中,不需要取樣,因為只生成一個tree)
val baggedInput = BaggedPoint
.convertToBaggedRDD(treeInput, strategy.subsamplingRate, numTrees, withReplacement, seed)
.persist(StorageLevel.MEMORY_AND_DISK)
- 新建樹根root,放到queue中,迴圈直到佇列為空
- 選擇多個訓練樹節點,同時進行訓練,根據指定的
maxMemoryUsage
進行個數計算
val (nodesForGroup, treeToNodeToIndexInfo) =
RandomForest.selectNodesToSplit(nodeQueue, maxMemoryUsage, metadata, rng)
- 按照Gini係數,找到當前樹節點中,最佳的feature分裂點和最佳bin分割點
RandomForest.findBestSplits(baggedInput, metadata, topNodes, nodesForGroup,
treeToNodeToIndexInfo, splits, nodeQueue, timer, nodeIdCache)- 遍歷資料,mapPartition,每個樹節點LearnNode維護一個DTStatsAggregator(存放,每個feature的每個bin的資料個數)
- 進行DTStatsAggregator的聚合merge
- 按照Gini係數,找到最佳的feature下的最佳split
- 選擇多個訓練樹節點,同時進行訓練,根據指定的
引數設定
可以通過設定一些引數,調整演算法或調優,詳細參考spark官網介紹
- 演算法設定
- algo:決策樹型別,分類或迴歸,Classification or Regression
- numClasses: 分類問題設定分類個數
- categoricalFeaturesInfo:指定哪些feature是離散值,並指定離散值的個數
- 停止條件設定
- maxDepth:樹最大深度
- minInstancesPerNode:每個樹節點最小的訓練資料個數,如果小於此值,則不進行分裂
- minInfoGain:最小資訊增益,決定當前樹節點是否進行分裂
- 調優引數
- maxBins:用於連續特徵值的分散化,最多劃分類個數
- maxMemoryInMB:增大,可以提高同時訓練的樹節點的個數,從而減少訓練時間,但是,每次訓練會增大資料的傳輸量
- subsamplingRate:訓練森林時使用,每次取樣的比例
- impurity:純度度量函式,必須和演算法algo相匹配