機器學習之 決策樹(Decision Tree)python實現

完美_並不美發表於2018-06-12
  1. 機器學習 之線性迴歸
  2. 機器學習 之邏輯迴歸及python實現
  3. 機器學習專案實戰 交易資料異常檢測
  4. 機器學習之 決策樹(Decision Tree)
  5. 機器學習之 決策樹(Decision Tree)python實現
  6. 機器學習之 PCA(主成分分析)
  7. 機器學習之 特徵工程
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from math import log
複製程式碼

我們使用西瓜書中的一個資料集,來進行我們的決策樹的建立

data = pd.read_csv("decision_tree_data3.txt",names=['編號','色澤','根蒂','敲聲','紋理','臍部','觸感','密度','含糖率','好瓜' ])
data.head()
複製程式碼
編號 色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
0 1 青綠 蜷縮 濁響 清晰 凹陷 硬滑 0.697 0.460
1 2 烏黑 蜷縮 沉悶 清晰 凹陷 硬滑 0.774 0.376
2 3 烏黑 蜷縮 濁響 清晰 凹陷 硬滑 0.634 0.264
3 4 青綠 蜷縮 沉悶 清晰 凹陷 硬滑 0.608 0.318
4 5 淺白 蜷縮 濁響 清晰 凹陷 硬滑 0.556 0.215

首先,我們需要將資料集做下處理,將對應文字轉換成離散型資料

# def initdata_feature(data):
#     len_columns = data.shape[1]
#     data_columns = data.columns
#     for i in range(len_columns):
#         if(i>0 and i<len_columns-3):
#             str_values = data.iloc[:,i].unique()
#             for j in range(len(str_values)):
#                 data.loc[data[data_columns[i]]==str_values[j],data_columns[i]] = j
def initdata_y(data):
    data.loc[data.好瓜 == '是 ','好瓜'] = 1
    data.loc[data.好瓜 == '否 ','好瓜'] = 0
複製程式碼

測試下看看

# initdata_feature(data)
initdata_y(data)
data
複製程式碼
編號 色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
0 1 青綠 蜷縮 濁響 清晰 凹陷 硬滑 0.697 0.460 1
1 2 烏黑 蜷縮 沉悶 清晰 凹陷 硬滑 0.774 0.376 1
2 3 烏黑 蜷縮 濁響 清晰 凹陷 硬滑 0.634 0.264 1
3 4 青綠 蜷縮 沉悶 清晰 凹陷 硬滑 0.608 0.318 1
4 5 淺白 蜷縮 濁響 清晰 凹陷 硬滑 0.556 0.215 1
5 6 青綠 稍蜷 濁響 清晰 稍凹 軟粘 0.403 0.237 1
6 7 烏黑 稍蜷 濁響 稍糊 稍凹 軟粘 0.481 0.149 1
7 8 烏黑 稍蜷 濁響 清晰 稍凹 硬滑 0.437 0.211 1
8 9 烏黑 稍蜷 沉悶 稍糊 稍凹 硬滑 0.666 0.091 0
9 10 青綠 硬挺 清脆 清晰 平坦 軟粘 0.243 0.267 0
10 11 淺白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 0
11 12 淺白 蜷縮 濁響 模糊 平坦 軟粘 0.343 0.099 0
12 13 青綠 稍蜷 濁響 稍糊 凹陷 硬滑 0.639 0.161 0
13 14 淺白 稍蜷 沉悶 稍糊 凹陷 硬滑 0.657 0.198 0
14 15 烏黑 稍蜷 濁響 清晰 稍凹 軟粘 0.360 0.370 0
15 16 淺白 蜷縮 濁響 模糊 平坦 硬滑 0.593 0.042 0
16 17 青綠 蜷縮 沉悶 稍糊 稍凹 硬滑 0.719 0.103 0

先把編號那個無用的特徵去掉

data = data.drop('編號', axis = 1)
data
複製程式碼
色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
0 青綠 蜷縮 濁響 清晰 凹陷 硬滑 0.697 0.460 1
1 烏黑 蜷縮 沉悶 清晰 凹陷 硬滑 0.774 0.376 1
2 烏黑 蜷縮 濁響 清晰 凹陷 硬滑 0.634 0.264 1
3 青綠 蜷縮 沉悶 清晰 凹陷 硬滑 0.608 0.318 1
4 淺白 蜷縮 濁響 清晰 凹陷 硬滑 0.556 0.215 1
5 青綠 稍蜷 濁響 清晰 稍凹 軟粘 0.403 0.237 1
6 烏黑 稍蜷 濁響 稍糊 稍凹 軟粘 0.481 0.149 1
7 烏黑 稍蜷 濁響 清晰 稍凹 硬滑 0.437 0.211 1
8 烏黑 稍蜷 沉悶 稍糊 稍凹 硬滑 0.666 0.091 0
9 青綠 硬挺 清脆 清晰 平坦 軟粘 0.243 0.267 0
10 淺白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 0
11 淺白 蜷縮 濁響 模糊 平坦 軟粘 0.343 0.099 0
12 青綠 稍蜷 濁響 稍糊 凹陷 硬滑 0.639 0.161 0
13 淺白 稍蜷 沉悶 稍糊 凹陷 硬滑 0.657 0.198 0
14 烏黑 稍蜷 濁響 清晰 稍凹 軟粘 0.360 0.370 0
15 淺白 蜷縮 濁響 模糊 平坦 硬滑 0.593 0.042 0
16 青綠 蜷縮 沉悶 稍糊 稍凹 硬滑 0.719 0.103 0

下面就開始實現決策樹演算法,上篇文章已經知道,要根據樣本集建立一棵決策樹,具體演算法流程如下:

機器學習之 決策樹(Decision Tree)python實現

下面我們來分模組進行實現。

首先,來看下給定資料集的資訊熵的求解

#求對應資料集的資訊熵
def getInfoEntropy(data):
    #print('################################')
    #print(data)
    count_class = pd.value_counts(data.iloc[:,-1], sort=True)  #根據輸出值,統計不同樣本個數
    #print(count_class)
    data_count = len(data.iloc[:,-1])
    #print(data_count)
    Entropy = 0.0
    for i in range(len(count_class)):
        p = count_class.iloc[i]/data_count
        Entropy = Entropy + (-p * log(p,2))
    #print('當前資料集的資訊熵為:',Entropy)
    return Entropy
複製程式碼

測試下看看,求取下整個樣本集的資訊熵

getInfoEntropy(data)
複製程式碼
0.9975025463691153
複製程式碼

下來我們實現下,根據對應特徵,劃分資料。需要分兩種情況

  1. 離散型特徵,直接根據離散的相應類別進行劃分
  2. 連續型資料,需要參照資料離散化,選出最優的劃分值。具體原理可檢視上篇文章中的連續型特徵處理

下面來看下具體程式碼實現

#離散型資料劃分
def split_data(data, column):
    splt_datas = pd.Series()   #將劃分的多個資料集儲存在Series中
    str_values = data.iloc[:,column].unique()  #獲取當前資料集中,對應特徵的所有類別
    for i in range(len(str_values)):   #遍歷對應類別,找出類別所對應的資料集
        df = data.loc[data.iloc[:,column] == str_values[i]]
#         print(df)
        splt_datas[str(i)] = df
    return splt_datas


#連續型資料劃分
#返回劃分後的左右兩個資料集以及所對應的最優劃分點,還有以此劃分點進行劃分資料後,對應的資訊熵
def split_continuous(data,column):
    splt_datas = pd.Series()
    series_data_sort = data.iloc[:,column].sort_values()  #對應對應連續型特徵的在當前資料集中的所有值,進行從小到大排序
    split_values = []   #建立一個list,用於儲存所有的劃分點
#     print(series_data_sort)
    for i in range(len(series_data_sort)-1):    #求得所有劃分點
        split_values.append((series_data_sort.iloc[i] + series_data_sort.iloc[i+1])/2)  # 注意,這塊不能用series_data_sort[i]
    best_split_value = 0.    #所要找出的最佳劃分點
    minInfoGain = 100.             
#     print(split_values)
    for i in range(len(split_values)):   #遍歷所有劃分點
       # print('split_values[i]==',split_values[i])
        #根據對應劃分點,將資料集劃分為左右兩個資料集(即二分)
        left_data = data.loc[data.iloc[:,column]<=split_values[i]]
        right_data = data.loc[data.iloc[:,column]>split_values[i]]
        #求得對應資訊熵
        InfoGain = len(left_data)/len(data) * getInfoEntropy(left_data) + len(right_data)/len(data) * getInfoEntropy(right_data)
        #print('InfoGain====',InfoGain)
        if(InfoGain < minInfoGain):   #找出最小的資訊熵
            minInfoGain = InfoGain
            best_split_value = split_values[i]
    left_data = data.loc[data.iloc[:,column]<=best_split_value]
    right_data = data.loc[data.iloc[:,column]>best_split_value]
    series = pd.Series()
    series['0'] = left_data
    series['1'] = right_data
    return series,best_split_value,minInfoGain
複製程式碼

測試下看看

seris = split_data(data,0)
for i in range(len(seris)):
    print (seris.iloc[i])
複製程式碼
    色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
0   青綠  蜷縮  濁響  清晰  凹陷  硬滑  0.697  0.460   1
3   青綠  蜷縮  沉悶  清晰  凹陷  硬滑  0.608  0.318   1
5   青綠  稍蜷  濁響  清晰  稍凹  軟粘  0.403  0.237   1
9   青綠  硬挺  清脆  清晰  平坦  軟粘  0.243  0.267   0
12  青綠  稍蜷  濁響  稍糊  凹陷  硬滑  0.639  0.161   0
16  青綠  蜷縮  沉悶  稍糊  稍凹  硬滑  0.719  0.103   0
    色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
1   烏黑  蜷縮  沉悶  清晰  凹陷  硬滑  0.774  0.376   1
2   烏黑  蜷縮  濁響  清晰  凹陷  硬滑  0.634  0.264   1
6   烏黑  稍蜷  濁響  稍糊  稍凹  軟粘  0.481  0.149   1
7   烏黑  稍蜷  濁響  清晰  稍凹  硬滑  0.437  0.211   1
8   烏黑  稍蜷  沉悶  稍糊  稍凹  硬滑  0.666  0.091   0
14  烏黑  稍蜷  濁響  清晰  稍凹  軟粘  0.360  0.370   0
    色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
4   淺白  蜷縮  濁響  清晰  凹陷  硬滑  0.556  0.215   1
10  淺白  硬挺  清脆  模糊  平坦  硬滑  0.245  0.057   0
11  淺白  蜷縮  濁響  模糊  平坦  軟粘  0.343  0.099   0
13  淺白  稍蜷  沉悶  稍糊  凹陷  硬滑  0.657  0.198   0
15  淺白  蜷縮  濁響  模糊  平坦  硬滑  0.593  0.042   0
複製程式碼
series,best_split_value,minInfoGain  = split_continuous(data,6)
for i in range(len(series)):
    print (series.iloc[i])
複製程式碼
    色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
9   青綠  硬挺  清脆  清晰  平坦  軟粘  0.243  0.267   0
10  淺白  硬挺  清脆  模糊  平坦  硬滑  0.245  0.057   0
11  淺白  蜷縮  濁響  模糊  平坦  軟粘  0.343  0.099   0
14  烏黑  稍蜷  濁響  清晰  稍凹  軟粘  0.360  0.370   0
    色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
0   青綠  蜷縮  濁響  清晰  凹陷  硬滑  0.697  0.460   1
1   烏黑  蜷縮  沉悶  清晰  凹陷  硬滑  0.774  0.376   1
2   烏黑  蜷縮  濁響  清晰  凹陷  硬滑  0.634  0.264   1
3   青綠  蜷縮  沉悶  清晰  凹陷  硬滑  0.608  0.318   1
4   淺白  蜷縮  濁響  清晰  凹陷  硬滑  0.556  0.215   1
5   青綠  稍蜷  濁響  清晰  稍凹  軟粘  0.403  0.237   1
6   烏黑  稍蜷  濁響  稍糊  稍凹  軟粘  0.481  0.149   1
7   烏黑  稍蜷  濁響  清晰  稍凹  硬滑  0.437  0.211   1
8   烏黑  稍蜷  沉悶  稍糊  稍凹  硬滑  0.666  0.091   0
12  青綠  稍蜷  濁響  稍糊  凹陷  硬滑  0.639  0.161   0
13  淺白  稍蜷  沉悶  稍糊  凹陷  硬滑  0.657  0.198   0
15  淺白  蜷縮  濁響  模糊  平坦  硬滑  0.593  0.042   0
16  青綠  蜷縮  沉悶  稍糊  稍凹  硬滑  0.719  0.103   0
複製程式碼

接下來,我們要做的就是,給定一個資料集,我們需要求得最優的劃分特徵,先來來看下程式碼實現

# 查詢當前資料集data 的 最優劃分特徵。返回對應最優特徵在資料集data中的索引
def find_best_feature(data):
    best_feature_index = 0    #用來儲存最優劃分特徵的索引
    minInfoGain = 100.      #儲存資訊增益
    samplenumber = len(data)   #當前資料集的個數
    best_split_value_return = 0.  #如果最優劃分特徵是個連續型別的,則還需要儲存對應的連續特徵的最優劃分點
    best_split_value = 0.
    best_Series = pd.Series()
    for i in range(data.shape[1]-1):    #遍歷資料集的所有特徵
        InfoGain = 0.
        series = pd.Series()
        if(i < data.shape[1]-3):    #離散型屬性
            series = split_data(data, i)   #根據特徵劃分資料,將劃分的多個資料集(DataFrame)儲存在一個Series中返回    
            for j in range(len(series)):
                df = series[j]
                InfoGain = InfoGain +len(df)/samplenumber *(getInfoEntropy(df))
#             print('InfoGain==',InfoGain,'----i=',i)
        else:                      #連續型屬性
            series,best_split_value, InfoGain = split_continuous(data,i)
#             print('InfoGain==',InfoGain,'----i=',i)
        if(InfoGain < minInfoGain):
            minInfoGain = InfoGain
            InfoGain = 0.0
            best_feature_index = i
            best_Series = series
            if(i >= data.shape[1]-3):
                best_split_value_return = best_split_value
     
    return data.columns[best_feature_index],best_Series,best_split_value_return

複製程式碼

測試下看看

find_best_feature(data)
複製程式碼
('紋理', 0        色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
 0...
 1        色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
 6...
 2        色澤  根蒂  敲聲  紋理  臍部  觸感     密度    含糖率  好瓜
 1...
 dtype: object, 0.0)
複製程式碼

接下來就要實現決策樹的構建了

#建立樹模型
def creat_Tree(data):
    y_values = data.iloc[:,-1].unique()   #得到當前資料集的y的類別
    if(len(y_values) == 1):             #如果只剩下一個類別,說明已經是純淨的資料,不需要再分,直接返回
        return y_values[0]
    flag = 0
    for i in range(data.shape[1]-1):   #當前節點中的所有樣本在當前所剩屬性集中取值相同,則直接返回當前資料集中類別樣本多的那個類別
        if(len(data.iloc[:,i].unique()) != 1):
            flag = 1
            break
    if(flag == 0):
        value_count = pd.value_counts(data.iloc[:,-1])
        return value_count.index[0]
    best_feature, best_Series,best_split_value = find_best_feature(data)  #尋找最優特徵,返回最優特徵,劃分後的資料集,已經如果是連續型特徵,還需要劃分點
    Tree = {best_feature:{}}    #用字典來模擬樹
    for j in range(len(best_Series)):    #遍歷劃分後的資料集
        split_data = best_Series.iloc[j]
        value = ''
        if(best_split_value == 0.0):    #說明是離散型特徵
            value = split_data.loc[:,best_feature].unique()[0]   #獲取對應劃分的特徵中,對應的特徵類別
            split_data = split_data.drop(best_feature, axis = 1) #離散型型特徵,用完後需要刪除
        else:                          #否則,說明是連續型特徵
            if(j == 0):
                value = '<='+str(best_split_value)
            else:
                value = '>'+str(best_split_value)
        Tree[best_feature][value] = creat_Tree(split_data)   #採用遞迴思想,繼續構建
    return Tree
    
複製程式碼
Tree = creat_Tree(data)
Tree
複製程式碼
{'紋理': {'模糊': 0,
  '清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}},
  '稍糊': {'觸感': {'硬滑': 0, '軟粘': 1}}}}
複製程式碼

接下來,來實現下,使用訓練出來的決策樹,對新的資料進行分類

#預測一個樣本
def classification_one(Tree, data):
    print(Tree)
    first_key = list(Tree.keys())[0]  #獲取根節點的key
    first_value = Tree[first_key]     #獲取根節點對應的value
    result = -1   #初始化,用來儲存當前節點的結果
    if('<' in list(first_value.keys())[0]):     #連續型特徵
        #解釋下下面兩行程式碼,裡面的 list(first_value.keys())[0] 獲取來的就是‘<=0.38...’這種格式,需要從這個裡面解析出0.38...這個分割點
        left_key =  list(first_value.keys())[0]  #'<=分割點'
        right_key =  list(first_value.keys())[1] #'>分割點'
        split_poit = float(''.join(list(left_key)[2:]))  # '分割點'
        if(data[first_key] <= split_poit):   #如果屬於左分支
            if(isinstance(first_value[left_key], dict)):   #判斷是否是葉子節點,如果對應的value還是一個dict字典,則說明是個非葉子節點,繼續遞迴
                result = classification_one(first_value[left_key],data)
            else:                                         #如果是葉子節點,返回結果值
                result = first_value[left_key]
        else:                              #如果屬於左分支
            if(isinstance(first_value[right_key], dict)):
                result = classification_one(first_value[right_key],data)
            else:
                result = first_value[right_key]
    else:                        #離散型特徵
        if(isinstance(first_value[data[first_key]], dict)):
            result = classification_one(first_value[data[first_key]],data)
        else:
            result = first_value[data[first_key]]
    return result

#預測多個樣本
def classification_more(Tree, data):
    result_list = []
    for i in range(data.shape[0]):
        result = classification_one(Tree, data.iloc[i])
        result_list.append(result)
    return result_list
複製程式碼
classification_more(Tree,data)
複製程式碼
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}





[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
複製程式碼

我們還是使用的上面的那個資料集用來驗證,可以看到,已經完全擬合了訓練集,

但是,這樣真的好嗎?正如上篇文章說的,決策樹如果不進行剪枝的話,肯定最後會一直分下去,直到所分的各個資料集完全是純淨的,這樣,非常容易導致過擬合現象。所以,還需要進行剪枝操作。具體程式碼這塊不演示了,只要掌握了整個決策樹構建的原理,實現起來也很簡單。

上面,演示的只是ID3演算法的相關實現,還有決策的其他演算法,例如C4.5決策樹演算法,主要區別就是最優劃分特徵的選擇標準不同。流程基本都是一致的。

相關文章