【机器学习】决策树算法(ID3算法及C4.5算法)的理解和应用

    技术2024-06-10  88

    文章目录

    【机器学习】决策树算法(ID3算法及C4.5算法)的理解和应用1.决策树的介绍1.1 ID3算法1.1.1 算法核心1.1.2 基本概念1.1.3 算法过程 1.2 C4.5算法1.2.1 算法核心1.2.2 基础概念1.2.3 算法过程 2.决策树分类实战2.1 C++实现ID3算法和C4.5算法2.1.1 安装Graphviz(可视化决策树) 2.2 Python下实现CART算法

    【机器学习】决策树算法(ID3算法及C4.5算法)的理解和应用

    1.决策树的介绍

    概念: 决策树是机器学习中一种特别常见的算法。决策树是一个预测模型,它在已知各种情况发生的概率下,训练而成的一个学习器,代表着对象属性和对象值的一种映射关系。

    决策树结构:

    根结点: 代表想要预测的目标的属性

    分支: 代表想要预测的目标的属性类别

    叶节点: 代表预测结果

    1.1 ID3算法

    1.1.1 算法核心

    在信息论中有一个理论,信息期望越小,信息增益越大。在ID3算法中我们的主要目的就是要找到信息增益最大的属性做为决策树的根结点来进行决策树的建立。

    1.1.2 基本概念

    这里我们拿一个例子(相亲满意程度预测)来解释:

    身高年龄是否有房工作单位满意程度175偏大有企业满意178偏小无政府满意180偏大无企业不满意178偏大无政府不满意180偏小有企业满意

    这里满意程度为预测结果,身高,年龄,是否有房,工作单位为构建决策树的属性。

    1.信息熵: 度量一个属性的信息量 S 代 表 训 练 样 本 集 合 , p 代 表 预 测 结 果 在 总 样 本 的 占 比 的 集 合 公 式 : E n t r o p y ( S ) = − ∑ i = 1 n p i l o g 2 p i 总 样 本 数 : 5 正 样 本 数 ( 满 意 ) : 3 负 样 本 数 ( 不 满 意 ) : 2 实 例 计 算 : E n t r o p y ( S ) = − 3 5 ⋅ l o g 2 ( 3 5 ) − 2 5 ⋅ l o g 2 ( 2 5 ) S代表训练样本集合,p代表预测结果在总样本的占比的集合\\ 公式:Entropy(S) = -\sum_{i=1}^n{p_i}log_2p_i\\ 总样本数:5\\正样本数(满意):3 \\ 负样本数(不满意):2\\ 实例计算:Entropy(S) = -\frac{3}{5}\cdot log_2(\frac{3}{5})-\frac{2}{5}\cdot log_2(\frac{2}{5}) SpEntropy(S)=i=1npilog2pi532Entropy(S)=53log2(53)52log2(52) 2.条件熵: 表示在已知属性X的情况下它的属性类别Y的不确定性(需要求所有属性的条件熵) 公 式 : E n t r o p y ( X ∣ Y ) = − ∑ i = 1 n p i l o g 2 p i ( p i = p ( X = X i ) ) 公式:Entropy(X|Y)=-\sum_{i=1}^np_ilog_2p_i (p_i=p(X=X_i)) Entropy(XY)=i=1npilog2pi(pi=p(X=Xi))

    求身高的条件熵 属 性 类 别 数 X 1 ( 175 ) = 1 属 性 类 别 数 X 2 ( 178 ) = 2 属 性 类 别 数 X 3 ( 180 ) = 2 X 1 = 1 ( 满 意 ) X 2 = 1 ( 满 意 ) + 1 ( 不 满 意 ) X 3 = 1 ( 满 意 ) + 1 ( 不 满 意 ) E n t r o p y ( X 1 ) = − 1 1 l o g 2 ( 1 1 ) − 0 1 l o g 2 ( 0 1 ) E n t r o p y ( X 2 ) = − 1 2 l o g 2 ( 1 2 ) − 1 2 l o g 2 ( 1 2 ) E n t r o p y ( X 3 ) = − 1 2 l o g 2 ( 1 2 ) − 1 2 l o g 2 ( 1 2 ) E n t r o p y ( 身 高 ) = 1 5 E n t r o p y ( X 1 ) + 2 5 E n t r o p y ( X 2 ) + 2 5 E n t r o p y ( X 3 ) 属性类别数 X_1(175)=1\\ 属性类别数 X_2(178)=2\\ 属性类别数 X_3(180)=2\\ X1=1(满意)\\ X2=1(满意)+1(不满意)\\ X3=1(满意)+1(不满意)\\ Entropy(X1)=-\frac{1}{1}log_2(\frac{1}{1})-\frac{0}{1}log_2(\frac{0}{1})\\ Entropy(X2)=-\frac{1}{2}log_2(\frac{1}{2})-\frac{1}{2}log_2(\frac{1}{2})\\ Entropy(X3)=-\frac{1}{2}log_2(\frac{1}{2})-\frac{1}{2}log_2(\frac{1}{2})\\ Entropy(身高)=\frac{1}{5}Entropy(X1)+\frac{2}{5}Entropy(X2)+\frac{2}{5}Entropy(X3) X1(175)=1X2(178)=2X3(180)=2X1=1()X2=1()+1()X3=1()+1()Entropy(X1)=11log2(11)10log2(10)Entropy(X2)=21log2(21)21log2(21)Entropy(X3)=21log2(21)21log2(21)Entropy()=51Entropy(X1)+52Entropy(X2)+52Entropy(X3)

    求年龄的条件熵 属 性 类 别 数 X 1 ( 偏 大 ) = 3 属 性 类 别 数 X 2 ( 偏 小 ) = 2 X 1 = 2 ( 不 满 意 ) + 1 ( 满 意 ) X 2 = 2 ( 满 意 ) E n t r o p y ( X 1 ) = − 1 3 l o g 2 1 3 − 2 3 l o g 2 2 3 E n t r o p y ( X 2 ) = − 2 2 l o g 2 2 2 − 0 2 l o g 2 0 2 E n t r o p y ( 年 龄 ) = 3 5 E n t r o p y ( X 1 ) + 2 5 E n t r o p y ( X 2 ) 属性类别数X1(偏大)=3\\ 属性类别数X2(偏小)=2\\ X1=2(不满意)+1(满意)\\ X2=2(满意)\\ Entropy(X1)=-\frac{1}{3}log_2\frac{1}{3}-\frac{2}{3}log_2\frac{2}{3}\\ Entropy(X2)=-\frac{2}{2}log_2\frac{2}{2}-\frac{0}{2}log_2\frac{0}{2}\\ Entropy(年龄)=\frac{3}{5}Entropy(X1)+\frac{2}{5}Entropy(X2) X1()=3X2()=2X1=2()+1()X2=2()Entropy(X1)=31log23132log232Entropy(X2)=22log22220log220Entropy()=53Entropy(X1)+52Entropy(X2)

    求是否有房的条件熵 属 性 类 别 数 X 1 ( 有 ) = 2 属 性 类 别 数 X 2 ( 无 ) = 3 X 1 = 2 ( 满 意 ) X 2 = 1 ( 满 意 ) + 2 ( 不 满 意 ) E n t r o p y ( X 1 ) = − 2 2 l o g 2 2 2 − 0 2 l o g 2 0 2 E n t r o p y ( X 2 ) = − 1 3 l o g 2 1 3 − 2 3 l o g 2 2 3 E n t r o p y ( 是 否 有 房 ) = 2 5 E n t r o p y ( X 1 ) + 3 5 E n t r o p y ( X 2 ) 属性类别数X1(有)=2\\ 属性类别数X2(无)=3\\ X1=2(满意)\\ X2=1(满意)+2(不满意)\\ Entropy(X1)=-\frac{2}{2}log_2\frac{2}{2}-\frac{0}{2}log_2\frac{0}{2}\\ Entropy(X2)=-\frac{1}{3}log_2\frac{1}{3}-\frac{2}{3}log_2\frac{2}{3}\\ Entropy(是否有房)=\frac{2}{5}Entropy(X1)+\frac{3}{5}Entropy(X2) X1()=2X2()=3X1=2()X2=1()+2()Entropy(X1)=22log22220log220Entropy(X2)=31log23132log232Entropy()=52Entropy(X1)+53Entropy(X2)

    求工作单位的条件熵 属 性 类 别 数 X 1 ( 企 业 ) = 3 属 性 类 别 数 X 2 ( 政 府 ) = 2 X 1 = 2 ( 满 意 ) + 1 ( 不 满 意 ) X 2 = 1 ( 满 意 ) + 1 ( 不 满 意 ) E n t r o p y ( X 1 ) = − 2 3 l o g 2 2 3 − 1 3 l o g 2 1 3 E n t r o p y ( X 2 ) = − 1 2 l o g 2 1 2 − 1 2 l o g 2 1 2 E n t r o p y ( 工 作 单 位 ) = 3 5 E n t r o p y ( X 1 ) + 2 5 E n t r o p y ( X 2 ) 属性类别数X1(企业)=3\\ 属性类别数X2(政府)=2\\ X1=2(满意)+1(不满意)\\ X2=1(满意)+1(不满意)\\ Entropy(X1)=-\frac{2}{3}log_2\frac{2}{3}-\frac{1}{3}log_2\frac{1}{3}\\ Entropy(X2)=-\frac{1}{2}log_2\frac{1}{2}-\frac{1}{2}log_2\frac{1}{2}\\ Entropy(工作单位)=\frac{3}{5}Entropy(X1)+\frac{2}{5}Entropy(X2) X1()=3X2()=2X1=2()+1()X2=1()+1()Entropy(X1)=32log23231log231Entropy(X2)=21log22121log221Entropy()=53Entropy(X1)+52Entropy(X2)

    **3.信息增益:**信息熵与条件熵的差 G a i n ( X ∣ Y ) = E n t r o p y ( S ) − E n t r o p y ( X ∣ Y ) G a i n ( 身 高 ) = E n t r o p y ( S ) − E n t r o p y ( 身 高 ) G a i n ( 年 龄 ) = E n t r o p y ( S ) − E n t r o p y ( 年 龄 ) G a i n ( 是 否 有 房 ) = E n t r o p y ( S ) − E n t r o p y ( 是 否 有 房 ) G a i n ( 工 作 单 位 ) = E n t r o p y ( S ) − E n t r o p y ( 工 作 单 位 ) Gain(X|Y)=Entropy(S)-Entropy(X|Y)\\ Gain(身高)=Entropy(S)-Entropy(身高)\\ Gain(年龄)=Entropy(S)-Entropy(年龄)\\ Gain(是否有房)=Entropy(S)-Entropy(是否有房)\\ Gain(工作单位)=Entropy(S)-Entropy(工作单位) Gain(XY)=Entropy(S)Entropy(XY)Gain()=Entropy(S)Entropy()Gain()=Entropy(S)Entropy()Gain()=Entropy(S)Entropy()Gain()=Entropy(S)Entropy()

    1.1.3 算法过程

    在求出各属性的信息增益后,将属性增益最大的属性做为决策树的根结点。然后至上向下递归建树。这里简单的距离介绍确定第一个根结点后的步骤。

    比如信息增益最大的属性为年龄,它有两个属性类别(即决策树的两个分支)

    属性类别为“偏大”时(即分支为“偏大”)

    身高年龄是否有房工作单位满意程度175偏大有企业满意178偏大无企业不满意180偏大无政府不满意

    属性类别为“偏小”时(即分支为“偏小”)

    身高年龄是否有房工作单位满意程度178偏小无政府满意180偏小有企业满意

    在此基础上在通过1.1.2中的基本概念求出各属性的信息增益,求出最大的信息增益在确定为根结点。 这里假设偏大分支下信息增益最大的属性是身高,偏小分支下信息增益最大的属性是工作单位。(如图)

    1.2 C4.5算法

    1.2.1 算法核心

    在信息增益的基础上引入分裂率的概念,从而决定决策树根结点的因素变成了信息增益率。

    1.2.2 基础概念

    分裂率: 引 用 上 述 例 子 来 计 算 属 性 为 身 高 时 的 分 裂 率 : 属 性 类 别 X 1 ( 175 ) = 1 属 性 类 别 X 2 ( 178 ) = 2 属 性 类 别 X 3 ( 180 ) = 2 s p l i t = − 1 5 l o g 2 1 5 − 2 5 l o g 2 2 5 − 2 5 l o g 2 2 5 引用上述例子来计算属性为身高时的分裂率:\\ 属性类别X_1(175)=1\\ 属性类别X_2(178)=2\\ 属性类别X_3(180)=2\\ split=-\frac{1}{5}log_2\frac{1}{5}-\frac{2}{5}log_2\frac{2}{5}-\frac{2}{5}log_2\frac{2}{5} X1(175)=1X2(178)=2X3(180)=2split=51log25152log25252log252 信息增益率: 信 息 增 益 率 等 于 信 息 增 益 除 以 分 裂 率 G a i n . r a t i o = G a i n s p l i t 信息增益率等于信息增益除以分裂率\\ Gain.ratio=\frac{Gain}{split} Gain.ratio=splitGain 其余概念与ID3算法相同。

    1.2.3 算法过程

    除了判断根结点属性的依据是信息增益率之外,其余过程与ID3算法相同。

    2.决策树分类实战

    2.1 C++实现ID3算法和C4.5算法

    功能菜单: 数据集: 数据集可以自己制作,这里我是用网上常用的数据(偷个懒),但制作时注意进行预处理操作。

    代码: 代码是在VS下编写的,我已经将代码的所有相关文件上传到Github上了,有兴趣的同学可以下载来试一下,除了功能6,需要安装配置Graphviz外(在下面有说明),其余功能可以直接实现。一共三个文件的decision_tree.cpp(主控源文件),pch.cpp(功能模块文件),pch.h(头文件)。 代码地址:https://github.com/huangzhaohong123/ID3-C4.5-decision_tree

    2.1.1 安装Graphviz(可视化决策树)

    DOT语言是用来描述图形的一种语言,而Graphviz则是用来处理这种语言的工具,适用于树结构的可视化。 该地址下下载graphviz-2.38.msi https://graphviz.gitlab.io/_pages/Download/Download_windows.html 下载后会出现 然后一直点next,直到出现安装路径时,它会给你默认安装路径(这里个人建议放在你自己熟悉的路径下,方便后面配置环境变量) 安装后 环境变量配置: 搜索—>编辑系统环境变量—>高级—>环境变量—>系统变量中找到path—>添加安装路径加上bin 有的电脑需要重启一下,使得环境变量生效。 bin文件下标注的gvedit可以直接调用该工具 dot语言可参考:https://blog.csdn.net/STILLxjy/article/details/86004519

    注意: 该工具在c++环境下不够友好,基本每次运行只能调用一次。

    2.2 Python下实现CART算法

    1.安装Graphviz(如上)2.pip install graphviz3.pip install pydotplus

    数据集(配置适合你的隐形眼镜)

    # -*- coding: UTF-8 -*- from sklearn.preprocessing import LabelEncoder, OneHotEncoder from sklearn.externals.six import StringIO from sklearn import tree import pandas as pd import numpy as np import pydotplus import os if __name__ == '__main__': os.environ["PATH"] += os.pathsep + 'E:/Graphviz-2.38/bin' #若环境配置不成功,则直接代码调用环境,E:/Graphviz-2.38/bin为我的安装路径 with open('D:/desktop/experience/lenses1.txt', 'r') as fr: #加载文件 lenses = [inst.strip().split('\t') for inst in fr.readlines()] #处理文件 #print(lenses) lenses_target = [] #提取每组数据的类别,保存在列表里 for each in lenses: #print(each[-1]) lenses_target.append(each[-1]) #print(lenses_target) lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate'] #特征标签 lenses_list = [] #保存lenses数据的临时列表 lenses_dict = {} #保存lenses数据的字典,用于生成pandas for each_label in lensesLabels: #提取信息,生成字典 for each in lenses: lenses_list.append(each[lensesLabels.index(each_label)]) lenses_dict[each_label] = lenses_list lenses_list = [] #print(lenses_dict) #打印字典信息 lenses_pd = pd.DataFrame(lenses_dict) #生成pandas.DataFrame print(lenses_pd) #打印pandas.DataFrame le = LabelEncoder() #创建LabelEncoder()对象,用于序列化 for col in lenses_pd.columns: #序列化 lenses_pd[col] = le.fit_transform(lenses_pd[col]) print(lenses_pd) #打印编码信息 clf = tree.DecisionTreeClassifier(max_depth = 4) #创建DecisionTreeClassifier()类 clf = clf.fit(lenses_pd.values.tolist(), lenses_target) #使用数据,构建决策树 dot_data = StringIO() tree.export_graphviz(clf, out_file = dot_data, #绘制决策树 feature_names = lenses_pd.keys(), class_names = clf.classes_, filled=True, rounded=True, special_characters=True) graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) graph.write_pdf("tree1.pdf") #保存绘制好的决策树,以PDF的形式存储。

    决策树可视化:

    Processed: 0.026, SQL: 9