> 文档中心 > 机器学习 - [源码实现决策树小专题]决策树中混杂度数值度量的Python编程实现(信息熵和基尼系数的计算)

机器学习 - [源码实现决策树小专题]决策树中混杂度数值度量的Python编程实现(信息熵和基尼系数的计算)

混杂度数值度量的Python编程实现


李俊才 的 CSDN 博客:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
邮箱 :[email protected]
CSDN 主页:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址:https://blog.csdn.net/qq_28550263/article/details/114883862

顾名思义,所谓混杂度就是指无序程度,一般使用“信息熵”(香浓熵)或者“及逆序数进行度量”。
阅读本文后推荐:信息增益与信息增益率计算的Python实现


目 录

1.信息熵(entropy)

  • 1.1 信息熵的概念
  • 1.2 信息熵的编程计算

2.基尼系数

  • 2.1.基尼系数的概念
  • 2.2.基尼系数的编程计算

3. 小结


1.信息熵(entropy)

1.1 信息熵的概念

信息熵是从热力学中借用过来提出以解决了对信息的量化度量问题的概念,把信息中排除了冗余后的平均信息量称为信息熵。信息熵的计算步骤为:

  • 先确定当前特征有多少取值(i=1,2,3,…),计算每种不同取值的概率pi
  • 在依据公式计算信息熵:
    H ( X ) = − ∑ i = 1 n p i ⋅ l o g 2 p i .H(X) = -\sum_{i=1}^n{pi·log_2{pi}}. H(X)=i=1npilog2pi.

1.2 信息熵的编程计算

from math import logdef entropy1(anArray):    """    计算信息熵(香浓熵)    """    entropy = 0.0 # 信息熵(香农熵)    feature_dict = {}    # 用字典键获取不重复的取值    for i in list(anArray): feature_dict.update({i:None,}) # 计算所有不同特征值取值的概率进而计算信息熵    for i in feature_dict:  # 这里每一个i是不重复的特征取值(每个特征出现一次) ct = list(anArray).count(i)# 计算某个特征取值为i的频数 pi = ct / len(anArray)     # 计算出特征值i在该特征中出现的概率 pi if pi == 0:  # 这个条件相当于人为定义log0=1     entropy = entropy - 1 else:     entropy = entropy - pi * log(pi,2)   # 以2位底求熵    return entropy

以上是自己实现对不同元素地频率进行统计以求取信息熵,理解起来难度略大。Python有个好处就是,很多模块都有人给你写好了,你只要import一下就可以通过更加便捷的方式完成你想要的功能。
使用Python内建模块collections中的Counter对象能方便地对数组中的不同元素出现次数进行统计以简化以上代码。collections.Counter 可以参见另外一篇博文【https://blog.csdn.net/qq_28550263/article/details/114867848)】)中的1.1 节
实现代码如下:

import numpy as npdef entropy2(anArray):    '''    计算信息熵(香浓熵)    '''    cnt = Counter(anArray)    data_length = len(anArray)    pis = []    for i in cnt: pis.append(cnt[i]/data_length)    hi = []    for pi in pis: if pi > 0:     hi.append(pi * np.log2(pi))    return -np.sum(hi)

2.基尼系数

2.1.基尼系数的概念

基尼系数也可以用于度量数据的混乱程度,比起信息熵而言基尼系数比较稳定,因为熵的值将随着所有取值情况的增多而呈现发散态势,但基尼系数最大为1,最小为0。这使得基尼系数在有些情况下用于混杂度的度量以实现某种算法时显得比基于信息熵的度量更方便。比如在决策树算法中,使用基于信息熵的信息增益总是会偏向于选取取值类型更多的特征,而这却不是我们所期待的。

基尼系数的计算步骤为:

  • 确定当前特征有多少取值(i=1,2,3,…),计算每种不同取值的概率Pk
  • 由以下公式计算基尼系数
    G i n i = ∑i=1 n p k ( 1 − p k ) = 1 − ∑i=1 n ( p k)2 Gini = \sum_{i=1}^n{pk(1-pk)}=1-\sum_{i=1}^n{(pk) ^2} Gini=i=1npk(1pk)=1i=1n(pk)2

2.2.基尼系数的编程计算

我们采用等式右边的式子,即Gini = 1-∑(k=1,n)|(Pk)^2实现求解如下:

import numpy as npdef Gini(anArray):    '''    计算基尼系数    '''    cnt = Counter(anArray)    data_length = len(anArray) Pks = []      # 先计算每种不同取值的概率Pk,装入列表Pks     for i in cnt: Pks.append(cnt[i]/data_length) Pk2s = [Pk**2 for Pk in Pks]# 再计算 1-∑(k=1,n)|(Pk)^2    return 1 - np.sum(Pk2s)

3. 小结

from math import logimport numpy as npdef impurity(anArray, impurity_t="entropy"):    """    计算混杂度 Parameters    ----------    anArray:     an Array like object,由某特征依次对应每条数据下的取值构成。    impurity_t:  str,表示混杂度的度量方式,只能是{"entropy","gini"}中的一个。    Return    result: float 为计算得到的impurity的数值。    """ cnt = Counter(anArray)    data_length = len(anArray)    pis = [cnt[i]/data_length for i in cnt] if impurity_t == "entropy":  # 信息熵:Entropy = -∑(i=1,n)|(pi·logpi) return -np.sum([pi * np.log2(pi) for pi in pis if pi > 0])    elif impurity_t == "gini":   # 基尼系数:Gini = 1-∑(k=1,n)|(Pk)^2 return 1 - np.sum([Pi**2 for Pi in pis])    else: raise ValueError("impurity_t can only be one of {'entropy','gini'}")

如果喜欢,记得一赞三连噢!

不搭配