機器學習理論入門:第二章 經典監督學習算法-決策樹

第二章 經典監督學習算法-決策樹

一、決策樹總體概覽

  1. 概念:是在已知各種情況發生概率的基礎上,通過構成決策樹來求取淨現值的期望值大於等於零的概率,評價項目風險,判斷其可行性的決策分析方法,是直觀運用概率分析的一種圖解法。由於這種決策分支畫成圖形很像一棵樹的枝幹,故稱決策樹。

  2. 能解決的問題
    –分類問題(較多使用)
    –迴歸問題

  3. 決策樹的種類(主要根據屬性劃分的依據來進行算法的分類)
    –ID3決策樹
    –C4.5決策樹
    –CART(Classification And Regression Tree)決策樹

  4. 優缺點
    在這裏插入圖片描述

二、信息論-信息熵

  1. 隨機事件及其信息
    –概念:隨機事件是在隨機試驗中,可能出現也可能不出現,而在大量重複試驗中具有某種規律性的事件叫做隨機事件
    –信息:對於一個隨機變量X,它的每一個可能值的出現都可以看作是一個信息,每當X的一個可能值被觀測到,我們稱不確定性減少了,即信息增加了
    在這裏插入圖片描述

  2. 信息熵
    –概念:是信息增益的數學期望
    在這裏插入圖片描述

  3. 熱力學中的熵
    –概念:表示系統混亂程度的量度

  4. 最大熵增原則
    –概念:當根據不完整的信息作爲依據進行推斷時,應該由滿足分佈限制條件的具有最大熵的概率分佈推得
    –推論:對於給定的方差,在任意的隨機變量中高斯隨機變量的熵最大

三、信息論-交叉熵與KL散度

  1. 聯合熵
    –概念:若X,Y是一對離散型隨機變量,且聯合概率分佈爲p(x,y),則X,Y的聯合熵爲:在這裏插入圖片描述
    –作用:描述了一對隨機變量的平均信息量

  2. 條件熵
    –概念:給定隨機變量X的情況下,隨機變量Y的條件熵爲:
    在這裏插入圖片描述

  3. 熵的連鎖規則
    在這裏插入圖片描述在這裏插入圖片描述

  4. 互信息
    –定義
    在這裏插入圖片描述
    –作用:反應的是知道了Y以後X的不確定性的減少量

  5. 相對熵(KL散度)
    –定義
    在這裏插入圖片描述
    –推論
    在這裏插入圖片描述

  6. 交叉熵(在深度學習中佔據重要地位)
    –定義
    在這裏插入圖片描述
    –作用:衡量估計出來的概率分佈和真實概率分佈之間的差異情況

四、屬性選擇的依據

  1. 決策樹的結構及作用
    –葉節點:輸出分類結果
    –內部節點:用於屬性測試
    –根節點:內節點的一種,位置特殊

  2. 決策樹的輸入
    在這裏插入圖片描述

  3. 根節點的一些特殊情況
    –若訓練集中的數據都屬於同一類,那麼將RootNode標記爲該類的葉節點。返回(返回也意味着算法的結束)
    –若屬性集爲空集,或者訓練集中的所有數據的所有屬性都相等,那麼將RootNode標記爲訓練集中出現次數最多的類的葉節點,返回

  4. 決策樹的一般算法流程
    在這裏插入圖片描述

  5. 信息增益
    –計算樣本集的信息熵
    –使用特定屬性a進行劃分的信息增益
    在這裏插入圖片描述
    –用法
    A)某個屬性的信息增益越大,則使用該屬性進行劃分所得的“純度提升”越大
    B)ID3算法使用信息增益作爲屬性選擇的依據
    –缺點
    A)對可取值數目較多的屬性有偏好

  6. 增益率
    –定義
    在這裏插入圖片描述
    –缺點
    A)對可取值數目較少的屬性有偏好
    –缺點的解決辦法(C4.5算法):先從屬性中找到信息增益高於平均水平的屬性,然後再從中選出增益率最高的

  7. 基尼指數
    –樣本集的基尼值公式
    在這裏插入圖片描述
    –基尼值作用:反映了隨機抽取兩個樣本,其所屬的類別不一致的概率
    –屬性a的基尼指數定義
    在這裏插入圖片描述
    –選擇標準:選擇基尼指數最小的屬性

五、剪枝操作

  1. 決策樹中的過擬合
    –概念:決策樹的生成過程有時候導致決策樹的分支過多(分支過多意味着考慮了過多的邊緣情況,邊緣情況很多時候由個體差異引起),從而導致過擬合

  2. 驗證集
    –概念:決策樹在構造的過程中使用驗證集進行測試,來決定當前屬性是否要進行分裂

  3. 剪枝的定義:將本來爲內部節點的節點變成葉節點的過程叫做剪枝

  4. 預剪枝(決策樹邊生成邊進行剪枝操作)
    –操作:在決策樹生成過程中,每個節點在劃分之前先在驗證集上進行一次測試,若當前節點的劃分無法提高泛化性能,則不做劃分處理,直接將此節點作爲葉節點(使得一些分支不能展開,降低了過擬合)

  5. 後剪枝(決策樹完全生成之後纔開始剪枝,並且是自下向上的進行)
    在這裏插入圖片描述
    –優點:樹的分支相對於預剪枝較多;泛化性能優於預剪枝
    –缺點:訓練時間較長

六、決策樹的拓展

  1. 連續值處理
    –連續屬性離散化
    A)C4.5算法採用“二分法”:假設有一個連續屬性a,那麼將數據劃分爲a≤t和a>t兩個部分
    在這裏插入圖片描述在這裏插入圖片描述
    在這裏插入圖片描述
    2.多變量決策樹
    –屬性的線性組合
    在這裏插入圖片描述

七、編程實現(Python)

from math import log
import operator


def calc_entropy(labels):
    # 計算信息熵
    label_num = len(labels)
    label_show_up_times_dict = {}
    for label in labels:
        if label not in label_show_up_times_dict.keys():
            label_show_up_times_dict[label] = 0
        label_show_up_times_dict[label] += 1
    entropy = 0.0
    for key in label_show_up_times_dict:
        prob = float(label_show_up_times_dict[key]) / label_num
        entropy += prob * log(prob, 2)
    return -entropy


def split_dataset(dataset, labels, index, value):
    # 根據特徵所在的位置index和特徵的值value,從原數據集中分割出那些值等於value的子集和標籤子集
    sub_dataset = []
    sub_labels = []
    fc_index = 0
    for fc in dataset:
        if fc[index] == value:
            # 如果遇到了值相等的,那麼把這個索引剔除,然後把剔除該索引之後的特徵向量加入到子集中
            temp = fc[:index]
            temp.extend(fc[index + 1:])
            sub_dataset.append(temp)
            # 把該特徵向量對應的標籤也挑出來
        fc_index += 1
    return sub_dataset, sub_labels


def select_best_attribute(dataset, labels):
    # 選擇最佳屬性,依據信息增益,即找到信息增益最大的屬性
    feature_num = len(dataset[0])  # 特徵個數
    base_entropy = calc_entropy(labels)  # 當前數據集的信息熵
    max_info_gain = -1  # 最大信息增益
    best_feature = -1  # 最佳的特徵所在的索引

    for i in range(feature_num):
        # 當前特徵位置上所有值的List
        feature_value_list = [example[i] for example in dataset]
        # 獲取所有可能的值(不重複)
        unique_vals = set(feature_value_list)
        # 此特徵的信息熵
        new_entropy = 0.0
        for value in unique_vals:
            # 獲取子集
            sub_dataset, sub_labels = split_dataset(dataset, i, value)
            # 子集佔的比例
            prob = float(len(sub_dataset)) / len(dataset)
            # new_entropy加上相應的部分
            new_entropy += prob * calc_entropy(sub_labels)
        # 計算當前特徵的信息增益
        info_gain = base_entropy - new_entropy
        if info_gain > max_info_gain:
            # 如果比best_info_gain高,那麼更新best_info_gain和best_feature
            max_info_gain = info_gain
            best_feature = i
    return best_feature


def majority_count(labels):
    # 選出所佔比例最高的label
    label_count = {}
    for vote in labels:
        if vote not in label_count.keys():
            label_count[vote] = 0
        label_count[vote] += 1
    sorted_class_count = sorted(label_count.iteritem(), key=operator.itemgetter(1), reverse=True)
    return sorted_class_count


def decision_tree(dataset, feature_names, labels):
    if labels.count(labels[0]) == len(labels):
        # label中所有元素都相等,及類別完全相同,停止劃分
        return labels[0]
    if len(dataset[0]) == 1:
        # 如果只有一個特徵
        return majority_count(labels)
    # 選出根節點的最最佳屬性
    best_feature_index = select_best_attribute(dataset, labels)

    best_feature_name = feature_names[best_feature_index]
    tree = {best_feature_name: {}}

    del (feature_names[best_feature_index])
    attr_values = [example[best_feature_index] for example in dataset]
    unique_vals = set(attr_values)
    for value in unique_vals:
        sub_dataset, sub_labels = split_dataset(dataset, best_feature_index, value)
        tree[best_feature_name][value] = decision_tree(sub_dataset, sub_labels)
    return tree
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章