当前位置: 首页 > news >正文

ID3决策树Python实现:从信息熵到分类预测的5个核心函数解析

ID3决策树Python实现:从信息熵到分类预测的5个核心函数解析

决策树作为机器学习中最经典的算法之一,其ID3实现版本以简洁高效著称。本文将深入剖析ID3算法的Python实现细节,聚焦信息熵计算、特征选择、递归建树等核心环节。不同于常规教程,我们将从代码层面解构算法本质,通过函数级分析揭示决策树的工作机制。

1. 信息熵计算:决策树的纯度标尺

信息熵是ID3算法最核心的概念,它量化了数据集的混乱程度。在Python中,我们通过calEnt函数实现这一计算:

from math import log def calEnt(dataSet): sampleCounts = len(dataSet) labelCounts = {} for sample in dataSet: label = sample[-1] labelCounts[label] = labelCounts.get(label, 0) + 1 Ent = 0.0 for key in labelCounts: prob = float(labelCounts[key])/sampleCounts Ent -= prob * log(prob, 2) return Ent

该函数的关键变量说明:

变量名作用
sampleCounts样本总数
labelCounts类别计数字典
prob类别概率

信息熵的计算过程实际上是对概率分布的负对数期望计算。当所有样本属于同一类别时,熵值为0,表示完全纯净。

2. 数据集划分:特征空间的切分艺术

splitDataSet函数实现了按特征值划分数据集的核心操作:

def splitDataSet(dataSet, index, value): retDataSet = [] for sample in dataSet: if sample[index] == value: reducedSample = sample[:index] + sample[index+1:] retDataSet.append(reducedSample) return retDataSet

这个函数实现了三个关键步骤:

  1. 遍历数据集寻找匹配特征值的样本
  2. 去除已使用的特征列(避免重复使用)
  3. 返回划分后的子集

提示:在递归建树过程中,每次划分后特征维度会减少,这正是删除已使用特征列的原因。

3. 特征选择:信息增益的最大化策略

chooseBestFeatureToSplit函数实现了ID3算法的特征选择策略:

def chooseBestFeatureToSplit(dataSet): featureCounts = len(dataSet[0]) - 1 baseEnt = calEnt(dataSet) bestGain = 0.0 bestFeature = -1 for i in range(featureCounts): featValues = {sample[i] for sample in dataSet} newEnt = 0.0 for value in featValues: subDataSet = splitDataSet(dataSet, i, value) prob = len(subDataSet)/float(len(dataSet)) newEnt += prob * calEnt(subDataSet) infoGain = baseEnt - newEnt if infoGain > bestGain: bestGain = infoGain bestFeature = i return bestFeature

信息增益计算的关键公式:

信息增益 = 划分前熵 - ∑(子集熵×子集比例)
  • 基尼指数:CART算法使用的替代指标
  • 增益率:C4.5算法对ID3的改进

4. 多数表决:处理边界情况的优雅方案

当特征用完但类别仍不纯时,majorLabel函数提供了解决方案:

import operator def majorLabel(labelList): labelCounts = {} for label in labelList: labelCounts[label] = labelCounts.get(label, 0) + 1 sortedLabels = sorted(labelCounts.items(), key=operator.itemgetter(1), reverse=True) return sortedLabels[0][0]

该函数的工作流程:

  1. 统计类别频率
  2. 按频率降序排序
  3. 返回最高频类别

5. 递归建树:决策树的骨架构建

createTree函数实现了决策树的递归构建过程:

def createTree(dataSet, labels): classList = [sample[-1] for sample in dataSet] # 终止条件1:类别完全相同 if classList.count(classList[0]) == len(classList): return classList[0] # 终止条件2:无特征可用 if len(dataSet[0]) == 1: return majorLabel(classList) # 选择最优特征 bestFeatIndex = chooseBestFeatureToSplit(dataSet) bestFeatLabel = labels[bestFeatIndex] # 构建树结构 myTree = {bestFeatLabel: {}} del(labels[bestFeatIndex]) # 递归构建子树 featValues = {sample[bestFeatIndex] for sample in dataSet} for value in featValues: subLabels = labels[:] myTree[bestFeatLabel][value] = createTree( splitDataSet(dataSet, bestFeatIndex, value), subLabels) return myTree

递归终止的两种情形:

  1. 当前节点所有样本属于同一类别
  2. 无剩余特征可供划分

6. 分类预测:决策树的应用实践

完成树构建后,我们通过classify函数实现预测:

def classify(inputTree, featLabels, testVec): firstStr = list(inputTree.keys())[0] secondDict = inputTree[firstStr] featIndex = featLabels.index(firstStr) for key in secondDict.keys(): if testVec[featIndex] == key: if type(secondDict[key]).__name__ == 'dict': classLabel = classify(secondDict[key], featLabels, testVec) else: classLabel = secondDict[key] return classLabel

预测过程遵循树结构的递归查询:

  1. 获取当前节点特征
  2. 根据测试数据特征值选择分支
  3. 递归查询直到叶节点

7. 实战演示:西瓜数据集的完整应用

让我们用经典的西瓜数据集演示完整流程:

# 创建数据集 def createDataSet(): dataSet = [ ['青绿','蜷缩','浊响','清晰','凹陷','硬滑','好瓜'], ['乌黑','蜷缩','沉闷','清晰','凹陷','硬滑','好瓜'], # ...更多数据... ] labels = ['色泽','根蒂','敲声','纹理','脐部','触感'] return dataSet, labels # 完整流程 dataSet, labels = createDataSet() tree = createTree(dataSet, labels[:]) print(classify(tree, labels, ['青绿','蜷缩','浊响','清晰','凹陷','硬滑']))

决策树的优势在可视化后尤为明显。通过以下方法可以绘制树形结构:

import matplotlib.pyplot as plt decisionNode = dict(boxstyle="sawtooth", fc="0.8") leafNode = dict(boxstyle="round4", fc="0.8") def plotNode(nodeTxt, centerPt, parentPt, nodeType): createPlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords='axes fraction', xytext=centerPt, textcoords='axes fraction', va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)

在实际项目中,ID3算法虽然简单直观,但也有其局限性。它倾向于选择取值较多的特征,且无法处理连续值特征。这些缺陷在后来的C4.5和CART算法中得到了改进。理解ID3的底层实现,为我们学习更复杂的树算法奠定了坚实基础。

http://www.jsqmd.com/news/1150586/

相关文章:

  • 随机森林回归特征重要性:5种评估方法对比与 Python 3.11 实战解读
  • 如何安全使用哔哩下载姬:B站视频离线观看的终极指南
  • 实对称矩阵正交对角化:从理论到NumPy/PyTorch的3个关键实现步骤
  • 高斯投影3度带与6度带:ArcGIS/PyQGIS 自动分带与坐标纠错
  • MindSpore 2.3.0 GPU 环境部署:Windows 11 下 Conda 与 Pip 源切换 3 步避坑
  • Perplexity Spaces团队协作效率翻倍:3个被92%团队忽略的权限配置关键点
  • K-S检验法 Python/Scipy 实战:3行代码完成正态/均匀/泊松分布检验
  • Windows本地部署Hermes Agent全指南:WSL2+Ubuntu24.04+Docker实战
  • FP-Growth 算法实战:Python 实现与 5 大核心步骤详解(附代码)
  • Windows上轻松安装安卓应用:APK安装器完全指南
  • Claude Code + MCP深度集成实战(附GitHub可运行Demo与权限配置密钥表)
  • Openclaw本地部署与技能集成全链路实战指南
  • ResNet-50 到 ConvNeXt:4 种 CNN 架构在 ImageNet 分类任务上的迁移学习效果对比
  • OpenCV Python 模板匹配旋转:3种黑边处理方案对比与最佳实践
  • T-Drive 2008 数据集实战:Python + OSMnx 实现 10 万轨迹点路网匹配与可视化
  • 逻辑回归与最大似然估计:从概率公式到 PyTorch 3 行代码实现
  • CGCS2000/WGS84/西安80 坐标系转换:七参数与四参数实战选择指南
  • Ornith 1.0 9B:轻量级Agentic编程模型在16GB Mac上的实测评估
  • Copilot与Cursor深度对比:从代码补全准确率、上下文理解力到私有部署支持,97%的工程师都选错了!
  • 网盘直链下载助手LinkSwift:一站式高效下载解决方案完全指南
  • 一文了解高超声速飞行器红外波段及窗口选择
  • MySQL 分库分表方案选型:Hash+Range组合策略在4000万用户表下的性能实测
  • 3种灰色预测模型对比:传统/新信息/新陈代谢 GM(1,1) 误差平方和选型指南
  • 中文 NLP 数据预处理实战:jieba 4.0 + 正则清洗 + 4 种停用词表对比
  • Simple Clock:重新定义纯净的时间管理体验
  • BEVFusion 算法详解
  • 2026 年 6 月 Visual Studio 更新:适配计费模式,新增信任验证与多项实用功能
  • Scikit-learn 1.5 实战:3步构建电商用户流失预测模型(准确率>92%)
  • 【对比评测】SendTomo与主流文件传输工具深度对比评测
  • COCO mAP 计算实战:从 IoU 0.5 到 0.95 的 10 个阈值解析与代码实现