機器學習 - 使用 ID3 算法從原理到實際舉例理解決策樹

一、什么是決策樹

1.基本概念

決策樹是一種樹形結構,由結點(node)有向邊(directed edge) 組成。其中結點分為兩類:

  • 內部結點(internal node):表示一個屬性(特征)
  • 葉結點(leaf node):表示一個類別

決策樹是常用的分類機器學習方法。

2.實際舉例說明

以 “相親對象分類系統” 為例構建簡單決策樹:

  • 內部結點(長方形):特征 “有無房子”“有無上進心”
  • 葉結點(橢圓形):類別 “值得考慮”“備胎”“Say Goodbye”
  • 分類邏輯:
  • 相親對象有房子→劃分為 “值得認真考慮”
  • 沒有房子但有上進心→劃分為 “備胎”既沒有房子也沒有上進心→劃分為 “Say Goodbye

實際分類中存在多個特征量,可構建多種決策樹,核心問題是如何篩選出最優決策樹

二、介紹建立決策樹的算法

決策樹算法的核心差異在于特征選擇指標,常見算法對比如下:

算法

特征選擇指標

核心邏輯

ID3

信息增益

信息增益越大,特征對降低數據不確定性的能力越強,優先作為上層結點

C4.5

信息增益率

解決 ID3 對多值特征的偏好問題,通過 “增益率 = 信息增益 / 特征固有值” 平衡選擇

CART

基尼指數

基尼指數越小,數據純度越高,優先選擇使基尼指數下降最多的特征

本文重點講解ID3 算法,以下是其核心概念與公式:

1. 某個分類的信息

單個分類的信息表示該分類的不確定性,公式為:

其中,P(x_i) 是選擇該分類的概率。

2. 熵(Entropy)

熵是隨機變量不確定性的度量,定義為信息的期望值,公式為:

其中,n 是分類的數目;熵值越大,數據不確定性越高。

3. 經驗熵(Empirical Entropy)

4. 條件熵(Conditional Entropy)

已知隨機變量 X 的條件下,隨機變量 Y 的不確定性,公式為:

其中,p_i?是 X=x_i?的概率,H(Y|X=x_i)?是 X=x_i?時 Y 的熵。

5. 信息增益(Information Gain)

樣本集 D?的經驗熵 H(D)?與特征 A?給定條件下 D?的經驗條件熵 H(D|A)?之差,公式為:

關鍵結論:特征的信息增益值越大,該特征對分類的貢獻越強,應優先作為決策樹的上層結點。

三、決策樹的一般流程

決策樹構建分為 6 個步驟,適用于各類決策樹算法:

  1. 收集數據:通過爬蟲、問卷、數據庫查詢等方式獲取原始數據,無固定方法。
  1. 準備數據:樹構造算法僅支持標稱型數據(離散類別數據),需將數值型數據離散化(如將 “年齡 20-30” 劃分為 “青年”)。
  1. 分析數據:構建樹后,通過可視化、誤差分析等方式驗證樹結構是否符合預期。
  1. 訓練算法:根據特征選擇指標(如 ID3 的信息增益),遞歸構建決策樹的數據結構。
  1. 測試算法:使用測試集計算決策樹的錯誤率,評估模型性能。
  1. 使用算法:將訓練好的決策樹應用于實際場景(如貸款審批、客戶分類),并持續迭代優化。

四、實際舉例構建決策樹

以 “貸款申請分類” 為例,使用 ID3 算法構建決策樹。

1. 數據集準備

貸款申請樣本數據表(原始)

ID

年齡

有工作

有自己的房子

信貸情況

類別(是否給貸款)

1

青年

一般

2

青年

3

青年

4

青年

一般

5

青年

一般

6

中年

一般

7

中年

8

中年

9

中年

非常好

10

中年

非常好

11

老年

非常好

12

老年

13

老年

14

老年

非常好

15

老年

一般

數據編碼(標稱化處理)
  • 年齡:0 = 青年,1 = 中年,2 = 老年
  • 有工作:0 = 否,1 = 是
  • 有自己的房子:0 = 否,1 = 是
  • 信貸情況:0 = 一般,1 = 好,2 = 非常好
  • 類別:no = 否,yes = 是
數據集代碼定義
from math import log
def createDataSet():dataSet = [[0, 0, 0, 0, 'no'],    # 樣本1[0, 0, 0, 1, 'no'],    # 樣本2[0, 1, 0, 1, 'yes'],   # 樣本3[0, 1, 1, 0, 'yes'],   # 樣本4[0, 0, 0, 0, 'no'],    # 樣本5[1, 0, 0, 0, 'no'],    # 樣本6[1, 0, 0, 1, 'no'],    # 樣本7[1, 1, 1, 1, 'yes'],   # 樣本8[1, 0, 1, 2, 'yes'],   # 樣本9[1, 0, 1, 2, 'yes'],   # 樣本10[2, 0, 1, 2, 'yes'],   # 樣本11[2, 0, 1, 1, 'yes'],   # 樣本12[2, 1, 0, 1, 'yes'],   # 樣本13[2, 1, 0, 2, 'yes'],   # 樣本14[2, 0, 0, 0, 'no']     # 樣本15]labels = ['年齡', '有工作', '有自己的房子', '信貸情況']  # 特征標簽labels1 = ['放貸', '不放貸']  # 分類標簽return dataSet, labels, labels1  # 返回數據集、特征標簽、分類標簽

2. 計算經驗熵 H (D)

數學計算

樣本集 D?共 15 個樣本,其中 “放貸(yes)”9 個,“不放貸(no)”6 個,經驗熵為:

代碼實現
def calcShannonEnt(dataSet):numEntires = len(dataSet)  # 數據集行數(樣本數)labelCounts = {}  # 存儲每個標簽的出現次數for featVec in dataSet:currentLabel = featVec[-1]  # 提取最后一列(分類標簽)if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1  # 標簽計數shannonEnt = 0.0  # 初始化經驗熵for key in labelCounts:prob = float(labelCounts[key]) / numEntires  # 標簽出現概率shannonEnt -= prob * log(prob, 2)  # 計算經驗熵return shannonEnt# 測試代碼
if __name__ == '__main__':dataSet, features, labels1 = createDataSet()print("數據集:", dataSet)print("經驗熵H(D):", calcShannonEnt(dataSet))  # 輸出:0.9709505944546686

3. 計算信息增益(選擇最優特征)

數學計算(以 “有自己的房子” 為例)

設特征 A_3(有自己的房子),取值為 “是(1)” 和 “否(0)”:

  • 子集 D_1(A_3=1):共 9 個樣本,均為 “yes”,經驗熵 H(D_1)=0
  • 子集 D_2(A_3=0):共 6 個樣本,“yes” 3 個、“no” 3 個
  • 經驗熵?
  • 條件熵?
  • 信息增益 (注:原文計算結果為 0.420,此處以原文代碼輸出為準)

其他特征的信息增益計算結果:

  • 年齡(A_1):0.083
  • 有工作(A_2):0.324
  • 信貸情況(A_4):0.363

結論:特征 “有自己的房子(A_3)” 信息增益最大,作為決策樹的根節點。

代碼實現
"""
函數:按照給定特征劃分數據集
參數:dataSet - 待劃分數據集axis - 特征索引value - 特征取值
返回:retDataSet - 劃分后的子集
"""
def splitDataSet(dataSet, axis, value):retDataSet = []for featVec in dataSet:if featVec[axis] == value:reducedFeatVec = featVec[:axis]  # 去掉當前特征列reducedFeatVec.extend(featVec[axis+1:])  # 拼接剩余列retDataSet.append(reducedFeatVec)return retDataSet"""
函數:選擇最優特征
參數:dataSet - 數據集
返回:bestFeature - 最優特征索引
"""
def chooseBestFeatureToSplit(dataSet):numFeatures = len(dataSet[0]) - 1  # 特征數量(減去分類列)baseEntropy = calcShannonEnt(dataSet)  # 基礎經驗熵bestInfoGain = 0.0  # 最優信息增益bestFeature = -1  # 最優特征索引for i in range(numFeatures):featList = [example[i] for example in dataSet]  # 提取第i列特征uniqueVals = set(featList)  # 特征的唯一取值newEntropy = 0.0  # 條件熵for value in uniqueVals:subDataSet = splitDataSet(dataSet, i, value)  # 劃分子集prob = len(subDataSet) / float(len(dataSet))  # 子集概率newEntropy += prob * calcShannonEnt(subDataSet)  # 累加條件熵infoGain = baseEntropy - newEntropy  # 計算信息增益print(f"第{i}個特征({labels[i]})的增益為:{infoGain:.3f}")if infoGain > bestInfoGain:bestInfoGain = infoGainbestFeature = ireturn bestFeature# 測試代碼
if __name__ == '__main__':dataSet, labels, labels1 = createDataSet()bestFeature = chooseBestFeatureToSplit(dataSet)print(f"最優特征索引值:{bestFeature}(對應特征:{labels[bestFeature]})")# 輸出:最優特征索引值:2(對應特征:有自己的房子)

4. 生成決策樹(遞歸構建)

核心邏輯
  1. 若樣本集所有樣本屬于同一類別,直接返回該類別(葉節點);
  2. 若無特征可劃分或樣本特征全相同,返回出現次數最多的類別(葉節點);
  3. 選擇最優特征作為當前節點,按特征取值劃分子集;
  4. 對每個子集遞歸執行上述步驟,生成子樹。
代碼實現
import operator"""
函數:統計出現次數最多的類別
參數:classList - 類別列表
返回:sortedClassCount[0][0] - 最多類別
"""
def majorityCnt(classList):classCount = {}for vote in classList:if vote not in classCount.keys():classCount[vote] = 0classCount[vote] += 1# 按類別次數降序排序sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]"""
函數:創建決策樹
參數:dataSet - 訓練集labels - 特征標簽featLabels - 存儲選擇的最優特征
返回:myTree - 決策樹(字典結構)
"""
def createTree(dataSet, labels, featLabels):classList = [example[-1] for example in dataSet]  # 提取所有類別# 情況1:所有樣本類別相同if classList.count(classList[0]) == len(classList):return classList[0]# 情況2:無特征可劃分或特征全相同if len(dataSet[0]) == 1 or len(labels) == 0:return majorityCnt(classList)# 情況3:遞歸構建樹bestFeat = chooseBestFeatureToSplit(dataSet)  # 最優特征索引bestFeatLabel = labels[bestFeat]  # 最優特征標簽featLabels.append(bestFeatLabel)myTree = {bestFeatLabel: {}}  # 決策樹字典del(labels[bestFeat])  # 刪除已使用的特征標簽featValues = [example[bestFeat] for example in dataSet]  # 最優特征的所有取值uniqueVals = set(featValues)  # 唯一取值for value in uniqueVals:subLabels = labels[:]  # 復制特征標簽(避免遞歸修改原列表)# 遞歸生成子樹myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels, featLabels)return myTree# 測試代碼
if __name__ == '__main__':dataSet, labels, labels

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96098.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96098.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96098.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【期末復習】嵌入式——S5PV210開發板

本文為嵌入式課程期末復習,僅供參考,所用課本:嵌入式Linux操作系統(李建祥著)。第一章1.1 簡述嵌入式微處理器數據存儲格式的大,小端模式。大端模式是指數據的高字節保存在內存的低地址中,而數據…

word文檔結尾批量插入圖片 docx批量插入圖片 指定幾張

如果你有一些word文檔。比如工作總結。你想每一個文檔里面都插入幾張圖片。插入到每個文檔的結尾,那么你可以使用這個工具。首先準備好你的文檔。然后把它們拖進右邊的方框中。拖動的時候,拖動第一個,然后準備好你的圖片。把你的圖片全部拖動…

CodeBuddy國際版又更新了體驗感1

CodeBuddy國際版又更新了 更好的使用體驗更少的資源消耗合理的消耗剩余資源使用起來也是很不錯的,這次更新自動模式想不到的少,可以用于其他的例如翻譯與寫測試用例或者其他的說明文檔等或者是閱讀一下項目更好了解項目總的上來說 使用體驗響應速度還是不…

基于開源AI智能名片鏈動2+1模式S2B2C商城小程序的公益課引流策略研究

摘要:本文聚焦公益課引流場景,探討開源AI智能名片、鏈動21模式與S2B2C商城小程序的融合應用。通過構建低成本用戶裂變體系,分析該技術組合在精準篩選、社群運營、激勵機制設計中的協同效應。研究提出"智能名片畫像-鏈動裂變激勵-S2B2C生…

季度最強策略:年化247%,回撤10%,夏普比率3.79。附大小盤輪動策略python源代碼。

原創內容第993篇,專注AGI,AI量化投資、個人成長與財富自由。 季度最強策略: 年化247%,回撤10%,夏普比率3.79。3積分可查看參數。 大小盤輪動的策略源代碼: 年化收益18.8%。 from engine import Task, Eng…

testng.xml

一、TestNG.xml 是 TestNG 測試框架的核心配置文件,用于組織和控制測試執行。通過它,可以靈活地管理測試套件、測試類、方法,并設置各種執行參數一個基本的 testng.xml文件通常以 ??DOCTYPE 聲明??開頭,并遵循特定的文檔類型定…

上架商品合規流程有多條,有的長,有的短,有的需要審核,校驗商品的合規性

博主介紹:?全網粉絲5W,全棧開發工程師,從事多年軟件開發,在大廠呆過。持有軟件中級、六級等證書。可提供微服務項目搭建與畢業項目實戰,博主也曾寫過優秀論文,查重率極低,在這方面有豐富的經驗…

[嵌入式][stm32h743iit6] 野火繁星stm32h743iit6開發板使用學習記錄

[嵌入式][stm32h743iit6] 野火繁星stm32h743iit6開發板使用學習記錄野火繁星STM32H743IIT6開發板使用學習速記問題描述嘗試解決野火繁星STM32H743IIT6開發板使用學習速記 問題描述 在使用該開發板學習stm32hal庫pwm開發時, 偶遇代碼無法驅動sg90舵機進行旋轉, 無論占空比設置…

Android 熱點開發的相關api總結

Android 熱點 一、前言熱點開發屬于系統級功能開發,涉及的核心 API 多為系統簽名權限保護(如android.permission.TETHER_PRIVILEGED),通常僅系統應用(如 Settings)可正常調用。 實際開發中,除基…

Claude Code 使用指南

Claude Code 使用指南 在 AI 輔助編程領域,我們正經歷從簡單的代碼補全到能夠自主執行復雜任務的“智能體”(Agent)的深刻變革。Claude Code 正是這一變革的杰出代表。它并非一個簡單的問答機器人,而是一個設計精密的編程協作系統…

Spring Boot常用注解-詳細解析+示例

1. SpringBootApplication詳細解析:組合注解,包含Configuration(標記配置類)、EnableAutoConfiguration(開啟自動配置)、ComponentScan(組件掃描)。啟動類標注后,Spring …

基于原神游戲物品系統小demo制作思路

概述 本文介紹了一個基于C的游戲物品與角色管理系統,該系統實現了游戲中的物品分類、角色屬性管理、隊伍組建以及背包物品使用等功能。該系統采用面向對象的設計原則,通過繼承和多態實現了可擴展的物品效果系統。 系統架構 1. 物品類型系統 系統定義了三…

Grounded-Segment-Anything 環境配置

Grounded-Segment-Anything 環境配置Grounded-Segment-Anything 介紹環境配置Install osx(非必須):Install RAM & Tag2Text:報錯 module ‘pkgutil‘ has no attribute ‘ImpImporter‘. Did you mean: ‘zipimporter‘?運行輸出分割文本提示檢測遠…

ZYNQ 定時器

一、ZYNQ定時器簡介 每個Cortex-A9處理器都有自己的專用32位定時器和32位看門狗定時器。兩個處理器共享一個全局64位定時器。這些計時器的時鐘始終為CPU頻率(CPU_3x2x)的1/2。在系統級,有一個24位看門狗定時器和兩個16位三重定時器/計數器。系…

Java8 Comparator接口 和 List Steam 排序使用案例

在Java中,Comparator接口主要用于實現自定義排序邏輯,適用于未實現Comparable接口或需要覆蓋默認比較規則的場景。以下是核心使用方法和注意事項:一、基礎用法?匿名內部類實現?傳統方式通過匿名內部類重寫compare()方法,例如對整…

word2vec模型案例

代碼實現:import torch.optim as optim from tqdm import tqdm, trange import numpy as np import torch from torch import nn import torch.nn.functional as FCONTEXT_SIZE 2raw_text """We are about to study the idea of a computational p…

< 自用文 OS 有關 > (續)發現正在被攻擊 后的自救 Fail2ban + IPset + UFW 工作流程詳解

繼上編:< 自用文 主機 USC 記錄:> 發現正在被攻擊 后的自救-CSDN博客 環境: 改進: 以下是把代碼,懶得寫,扔給了 AI ,讓它出的: Fail2ban IPset UFW 工作…

Linux —— 虛擬進程地址空間

🎁個人主頁:工藤新一 🔍系列專欄:C面向對象(類和對象篇) 🌟心中的天空之城,終會照亮我前方的路 🎉歡迎大家點贊👍評論📝收藏?文章 文章目錄虛…

簡單聊一聊js

JavaScript 是一種高級的、解釋型的編程語言。它是現代 Web 開發的三大核心基石之一,與 HTML 和 CSS 并列。?HTML?:負責網頁的結構和內容?(如標題、段落、圖片)。?CSS?:負責網頁的樣式和布局?(如顏色…

造粒機cad+設計說明書

摘要 隨著現代化工業的快速發展,生產出大量的固體廢棄物。這些廢棄物對環境造成了很大的污染,因此需要采取有效的措施進行處理。機械強壓式造粒機就是一種非常有效的處理工具,它可以將廢渣、廢料、飼料和化肥等材料通過機械強力擠壓&#xff…