机器学习 - 决策树中,信息增益、信息增益率计算以及最佳特征挑选的Python实现

简介: 本文介绍决策树中,信息增益、信息增益率计算以及最佳特征挑选的Python实现

信息增益、信息增益率计算 以及 最佳特征挑选 的Python实现


李俊才 的个人博客

已入驻阿里云博客

邮箱 :291148484@163.com
本文地址
- https://developer.aliyun.com/article/
- https://blog.csdn.net/qq_28550263/article/details/114891368

阅读本文前推荐先阅读:混杂度数值度量的Python编程实现https://blog.csdn.net/qq_28550263/article/details/114883862

阅读本文前推荐先阅读:决策树算法中数据集的划分https://blog.csdn.net/qq_28550263/article/details/114892718

导读:决策树是一种基于信息的学习算法。在决策树算法中需要不断地挑选出最佳特征,而挑选最佳特征地依据就是信息增益率

增益本身就具有相对地特性,表征某事物从一个状态到另一个状态后,某个指标的变化量。

在决策树算法中,信息增益指的是依据某个特征的取值划分数据集时数据集划分后相对于划分前,所能导致减少的信息不确定度

这也就是说信息增益即不确定度的降低值。当我们以信息熵(香浓熵,简称)作为不确定性的度量时,以数据集划分前的原始熵减去数据集划分后的剩余熵得到的值就是信息增益


【博文1】在我的博文https://blog.csdn.net/qq_28550263/article/details/114892718中已经详尽地介绍了数据集划分的思路、步骤,给出了源代码并举了两个例子。


【博文2】在我的博文https://blog.csdn.net/qq_28550263/article/details/114883862中,则给出了不确定度的计算方法,其中就包含了基于信息熵(香浓熵)的计算方法和基尼系数的计算方法。


对于以上内容我们都将用到。


目 录


1. 求解信息增益

2. 使用信息增益存在的问题与信息增益率

3. 基于信息增益率的最佳特征挑选


1. 求解信息增益

1.1 已经准备好的接口

(1)划分数据集函数(仅展示接口,具体内容请参阅【博文1】

defdividing_data_set(date_set,node_feature,node_feature_value):
"""    划分数据集    整个划分方法的思想是"记录索引-重索引"。简而言之就是先记住特征取值为指定取值的索引号,然    后依据记录索引号保对其它特征下同索引号的元素进行保留。最终实现留下当前划分数据条的目的。    Parameters    ----------    date_set: "dict"结构的数据集,其中键为”labels“的键值对对应为标签集(源于x_train),其余               的对应为特征取值键值对(源于y_train)。    node_feature:可以是num、str等类型,但是必须和date_set中的键的类型保持一致。表示需要划分               数据集的节点处对应的特征名。    node_feature_value:是对应与 node_feature 的一个特定取值。    Returns    -------    result : dict        返回子数据集字典,其形式与date_set保持一致。其中键`labels`对应的值类似是子标签集数组。    """

(2)混杂度求取函数(仅展示接口,具体内容请参阅【博文2】

defimpurity(anArray, impurity_t="entropy"):
"""    计算混杂度    Parameters    ----------    impurity_t:  str,表示混杂度的度量方式,只能是{"entropy","gini"}中的一个。    anArray:     an Array like object,由某特征依次对应每条数据下的取值构成。    Return    result: float        为计算得到的impurity的数值。    """

1.2 使用实例讲解

这里采用【博文1】中的例子:

importnumpyasnp# 定义模拟数据x_train=np.array([[1, 4, 2, 0, 3, 1, 1, 0, 1, 4, 2, 4, 4, 2, 4, 2, 0, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 3, 1, 3, 1, 3, 1, 1, 0, 1, 4, 3, 4, 4, 2],
       [0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 3, 0, 3, 1, 1, 0, 0, 4, 2, 2, 4, 1, 1, 0, -1, 0, 4, 0, -1, -1, 0, 0, 0, 0, 0, 0, 2],
       [4, 2, 2, 3, 1, 2, 1, 1, 0, 2, 1, 1, 1, 0, 3, 0, 3, 2, 2, 0, 0, 0, 0, 3, 1, 1, 2, 3, 4, 3, 1, 1, 3, 1, 2, 1, 1, 0, 1, 2, 2, 1, 0],
       [1, 4, 2, 2, 3, 1, 1, 0, 0, 2, 1, 1, 1, 0, 3, 4, 2, 2, 4, 1, 0, 1, 0, 3, 2, 2, 4, 3, 1, 2, -1, 2, 2, 1, 0, 1, -1, 0, 1, 1, 1, 0, 0],
       [1, 2, 2, 1, 3, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 4, 1, 2, 1, 0, 0, 0, 0, 2, 1, 1, 2, 3, 3, 0, -1, 2, 1, 3, 1, 1, 0, 0, 2, 3, 2, 1, 0],
       [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 3, 3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 2, 4, 2, 2, -1, 2, 2, 3, 0, 0, 0, 0, 2, 2, 2, 2, 0],
       [1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 3, 2, 1, 1, 0, 2, 2, 1, 0, 3, 3, 2, 1, 1, 3, 0, -2, -1, -1, 0, 1, 0, 2, 2, 1],
       [0, 0, 3, 3, 2, 0, 0, 0, 0, 3, 3, 3, 0, 2, 1, 3, 3, 3, 2, 1, 1, 0, 0, 3, 4, 4, 1, 2, 1, 0, 1, 2, 2, 1, -1, -1, 0, 0, 2, 1, 2, 1, 2],
       [2, 4, 2, 0, 2, 1, 0, 1, 0, 2, 2, 3, 4, 2, 2, 3, 0, 2, 0, 1, 1, 0, 0, 0, 3, 3, 0, 4, 2, 2, 1, 3, 1, 4, 0, -1, 1, 0, 3, 1, 2, 4, 0],
       [1, 4, 1, 0, 1, 0, 0, 0, 0, 3, 2, 3, 3, 4, 4, 1, 0, 1, 0, 1, 0, 1, 0, 0, 2, 1, 4, 2, 0, 4, 1, 3, 1, 3, -1, 0, -1, 0, 3, 2, 3, 2, 3]],)
y_train=np.array([1, 0, 0, 1, 0, 0, 1, 0, 0, 1]) 
features= ["feature_"+str(i) foriinrange(43)]  # 产生43个不同的特征名字# 转换为数据集字典date_set=dict(zip(features,x_train.T))
date_set.update({"labels":y_train})      # 将标签集(labels,也就是输出y们)也加入数据集

在【博文1】中,我们是假设了"feature_13"最为node_feature,也就是第一个”最佳特征“。但是当时只是假设的,并不是计算得出。到了本文,我的的任务就是要算出所有节点划分数据集前后的信息增益,取其最大者为真实的最佳特征。

不过我们仍然可以以"feature_13"为例,计算"feature_13"在划分前后的信息增益。

1.3 信息增益计算的实现

计算数据集划分前labels的熵作为划分前的熵,数据集划分后各个子数据集labels熵的和作为数据集划分后的熵。以此直接求取信息增益。

defgain(impurity_t, impurity_before_divide, data_set, probable_feature):
"""    计算信息增益    需要传入数据集划分前的不纯度、划分数据集所依赖特征对应的取值数组。考虑到在同一个节点测试不同子特征增益时都有用    到划分前的不纯度,为了提升运行效率故在gain()外计算好该节点分裂前的不纯度后再传入gain()函数。其中数据集划分前的    熵就是划分前的标签集labels的熵。其中按某特征划分后的不确定度,为依该特征各个取值划分的子数据集的中的标签集(即    该特征划分完后所有的子标签集)的不确定度总和。    Parameters    ----------    impurity_t:              str,不纯度的度量方式,只能是{"entropy","gini"}中的一个。    impurity_before_divide:  float,表示数据集划分前的不纯度。                data_set:               dict,划分前的数据集。    probable_feature:        str,用于划分数据集的特征。    Return    ------    result:      float,表征信息增益值。    """impurity_after_divide=0# 初始化数据集划分后的不存度为0forvalueinset(date_set[probable_feature]):         # 获取该特征所有的取值并使用集合去重,遍历之one_sublabel_array=dividing_data_set(           # 获取该子数据集中的标签集数组date_set=date_set, 
node_feature=probable_feature,
node_feature_value=value        )['labels']
impurity_after_divide=impurity(one_sublabel_array,impurity_t) # 累加每个子数据标签集的不存度returnimpurity_before_divide-impurity_after_divide# 做差得到这个特征的增益并返回impurity_t="entropy"# 使用信息熵度量混杂度              impurity_before_divide=impurity(date_set["labels"],impurity_t)     # 数据集划分前labels的混杂度probable_feature="feature_13"# 假设当前划分数据集用该特征gain(impurity_t, impurity_before_divide, date_set, probable_feature)

Out[i]: 0.9709505944546686

2. 使用信息增益存在的问题与信息增益率

由于取值越连续则不确定度越大,直接使用信息增益往往容易导致取值数量越多的特征则越容易被挑选出来。为了平衡特征取值趋于连续带来的影响,我们使用信息增益率作为信息增益的替代方案以选取最佳特征。

改为求解信息增益率的算法如下:

defgain_rate(impurity_t, impurity_before_divide, data_set, probable_feature):
"""    计算信息增益率    相对于信息增益的计算,信息增益率还要求解出由于该特征的不同取值带来的不确度。     - 若由于特征取值带来的不确定度为0,说明无特征取值连续化影响,直接返回信息增益;     - 若特征取值带来的不确定度不是0,则使用信息增益除以特征取证带来的不确定度。    Parameters    ----------    impurity_t:              str,不纯度的度量方式,只能是{"entropy","gini"}中的一个。    impurity_before_divide:  float,表示数据集划分前的不纯度。                data_set:               dict,划分前的数据集。    probable_feature:        str,用于划分数据集的特征。    Return    ------    result:      float,表征信息增益值。    """impurity_after_divide=0# 初始化数据集划分后的不存度为0forvalueinset(date_set[probable_feature]):         # 获取该特征所有的取值并使用集合去重,遍历之one_sublabel_array=dividing_data_set(           # 获取该子数据集中的标签集数组date_set=date_set, 
node_feature=probable_feature,
node_feature_value=value        )['labels']
impurity_after_divide=impurity(one_sublabel_array,impurity_t)     # 累加每个子数据标签集的不存度gain=impurity_before_divide-impurity_after_divide# 做差得到这个特征的增益feature_impurity=impurity(data_set[probable_feature],impurity_t)
gain_rate=gain/feature_impurityiffeature_impurity>0elsegainreturngain_rateimpurity_t="entropy"# 使用信息熵度量混杂度              impurity_before_divide=impurity(date_set["labels"],impurity_t)     # 数据集划分前labels的混杂度probable_feature="feature_13"# 假设当前划分数据集用该特征gain_rate(impurity_t, impurity_before_divide, date_set, probable_feature)

Out[i]:0.7134285408041596


3. 基于信息增益率的最佳特征挑选

这是本节最为简单的部分了,需要完成的工作包括:

  • 获取当前节点处所有的特征;
  • 依次假设每一个特征就是当前节点处分裂的最佳特征,划分数据集从而计算出这些特征各自再划分前后的信息增益率;
  • 比较:选取上一步中,实际划分前后信息增益率最大者作为当前节点处的最佳特征返回之。

实现代码如下:

defbest_feature(impurity_t,date_set):
"""    求取节点处的最佳特征    Parameters    ----------    date_set:    dict,与某个节点处的对应的数据集    Return    ------    result:     str,数据集date_set所属节点处可用于分裂的最佳特征    """features= [iforiindate_setifi!="labels"]                   # 获取数据集中当前节点处所有特征impurity_before_divide=impurity(date_set["labels"],impurity_t)    # 数据集划分前labels的混杂度max_gain_rate=-1# 不会小于0,因此随便给个负数初始值the_best_feature=""forprobable_featureinfeatures:
rate=gain_rate(impurity_t, impurity_before_divide, date_set, probable_feature)
ifrate>max_gain_rate:
max_gain_rate=ratethe_best_feature=probable_featurereturnthe_best_featureimpurity_t="entropy"best_feature(impurity_t,date_set)

Out[i]:‘feature_8’

目录
相关文章
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--代码生成技术
代码生成技术是人工智能与软件工程交叉领域的一项重要技术,它利用机器学习、自然语言处理和其他AI算法自动编写或辅助编写计算机程序代码。这一技术旨在提高编程效率、降低错误率,并帮助非专业开发者快速实现功能。以下是代码生成技术的概述及其典型应用场景。
15 6
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇——3D生成技术
在Python中,人工智能(AI)与3D生成技术的结合可以体现在多个方面,比如使用AI算法来优化3D模型的生成、通过机器学习来预测3D模型的属性,或者利用深度学习来生成全新的3D内容。然而,直接通过AI生成完整的3D模型(如从文本描述中生成)仍然是一个活跃的研究领域。 3D生成技术是一种通过计算机程序从二维图像或文本描述自动创建三维模型的过程。这一技术在近年来得到了飞速的发展,不仅为游戏、动画和影视行业带来了革命性的变革,还在虚拟现实、增强现实以及工业设计等多个领域展现出了巨大的应用潜力
7 2
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】python之人工智能应用篇--游戏生成技术
游戏生成技术,特别是生成式人工智能(Generative Artificial Intelligence, 简称Generative AI),正逐步革新游戏开发的多个层面,从内容创作到体验设计。这些技术主要利用机器学习、深度学习以及程序化内容生成(Procedural Content Generation, PCG)来自动创造游戏内的各种元素,显著提高了开发效率、丰富了游戏内容并增强了玩家体验。以下是生成式AI在游戏开发中的几个关键应用场景概述
6 2
|
3天前
|
机器学习/深度学习 JSON API
【Python奇迹】FastAPI框架大显神通:一键部署机器学习模型,让数据预测飞跃至Web舞台,震撼开启智能服务新纪元!
【8月更文挑战第16天】在数据驱动的时代,高效部署机器学习模型至关重要。FastAPI凭借其高性能与灵活性,成为搭建模型API的理想选择。本文详述了从环境准备、模型训练到使用FastAPI部署的全过程。首先,确保安装了Python及相关库(fastapi、uvicorn、scikit-learn)。接着,以线性回归为例,构建了一个预测房价的模型。通过定义FastAPI端点,实现了基于房屋大小预测价格的功能,并介绍了如何运行服务器及测试API。最终,用户可通过HTTP请求获取预测结果,极大地提升了模型的实用性和集成性。
13 1
|
3月前
|
机器学习/深度学习 存储 搜索推荐
利用机器学习算法改善电商推荐系统的效率
电商行业日益竞争激烈,提升用户体验成为关键。本文将探讨如何利用机器学习算法优化电商推荐系统,通过分析用户行为数据和商品信息,实现个性化推荐,从而提高推荐效率和准确性。
184 14
|
3月前
|
机器学习/深度学习 算法 搜索推荐
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
|
3月前
|
机器学习/深度学习 算法 数据可视化
实现机器学习算法时,特征选择是非常重要的一步,你有哪些推荐的方法?
实现机器学习算法时,特征选择是非常重要的一步,你有哪些推荐的方法?
71 1
|
3月前
|
机器学习/深度学习 数据采集 算法
解码癌症预测的密码:可解释性机器学习算法SHAP揭示XGBoost模型的预测机制
解码癌症预测的密码:可解释性机器学习算法SHAP揭示XGBoost模型的预测机制
220 0
|
3月前
|
机器学习/深度学习 数据采集 监控
机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?
机器学习-特征选择:如何使用递归特征消除算法自动筛选出最优特征?
606 0
|
3月前
|
机器学习/深度学习 人工智能 算法
探索机器学习中的支持向量机(SVM)算法
【2月更文挑战第20天】 在数据科学与人工智能的领域中,支持向量机(SVM)是一种强大的监督学习算法,它基于统计学习理论中的VC维理论和结构风险最小化原理。本文将深入探讨SVM的核心概念、工作原理以及实际应用案例。我们将透过算法的数学原理,揭示如何利用SVM进行有效的数据分类与回归分析,并讨论其在处理非线性问题时的优势。通过本文,读者将对SVM有更深层次的理解,并能够在实践中应用这一算法解决复杂的数据问题。
55 0