一、熵(Entropy)

1.1 概念

熵,在信息论中是用来刻画信息混乱程度的一种度量。
最早源于热力学,后应广泛用于物理、化学、信息论等领域。1850年,德国物理学家鲁道夫·克劳修斯首次提出熵的概念,用来表示任何一种能量在空间中分布的均匀程度。1948年,Shannon在Bell System Technical Journal上发表文章“A Mathematical Theory of Communication”,将信息熵的概念引入信息论中。本文所说的熵就是Shannon熵,即信息熵,解决了对信息的量化度量问题。

1.2 定义

H ( D ) = − ∑ i = 1 n p i l o g p i H(D) = -\displaystyle \sum_{i=1}^{n} p_i logp_i H(D)=i=1npilogpi
其中,

  • n 代表X的n种不同的离散取值;
  • p i p_i pi 代表了集合D取值为i的概率(比例);
  • log 为以2或者e为底的对数;
  • 从定义中可以看出变量的不确定性越大,熵也就越大,把它搞清楚所需要的信息量也就越大。

1.3 案例和代码

import math
from collections import Counter

def Entropy(DataList):
    '''
        计算随机变量 DataList 的熵
    '''
    counts = len(DataList)      # 总数量
    counter = Counter(DataList) # 每个变量出现的次数
    prob = {i[0]:i[1]/counts for i in counter.items()}      # 计算每个变量出现的比例 p
    H = - sum([i[1]*math.log2(i[1]) for i in prob.items()]) # 计算熵
    
    print("总数量:",counts)
    print("每个变量出现的次数:",counter)
    print("每个变量出现的比例:",prob)
    print("熵:",H)
    
    return H

if __name__ == "__main__":
    data_list_1 = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2, 3, 4, 5 ]
    data_list_2 = [1,1,1,1,2,2,2,2]
    data_list_3 = [1,1,1,1,1,1,1,2]
    data_list_4 = [1,2,2,2,2,2,2,2]
    data_list_5 = [1,9,9,9,9,9,9,9]

    print("----------数据集1")
    HX1 = Entropy(data_list_1)
    print("----------数据集2")
    HX2 = Entropy(data_list_2)
    print("----------数据集3")
    HX3 = Entropy(data_list_3)
    print("----------数据集4")
    HX4 = Entropy(data_list_4)
    print("----------数据集5")
    HX5 = Entropy(data_list_5)

在这里插入图片描述
可以看出:

  • 数据集1熵值大,说明1信息更混乱;
  • 数据集2熵值为1.0,说明各类别占比均等时,熵值会等于1;
  • 数据集3、4、5的熵值一样,说明信息熵只依赖出现的概率。

二、条件熵(Conditional Entropy)

2.1 概念

条件熵(Conditional Entropy)是在已知某一特征的条件下,度量目标变量的不确定性。它用于衡量在给定特征的信息后,目标变量的信息熵的期望值。条件熵是信息论中的重要概念,在构建决策树时,用于计算信息增益,从而帮助选择最佳分裂特征。

2.2 定义

定义在给定特征 A 的条件下,目标变量 Y 的信息熵为条件熵 H ( Y ∣ A ) H(Y|A) H(YA)
H ( Y ∣ A ) = ∑ v ∈ V a l u e s ( A ) ∣ D v ∣ ∣ D ∣ H ( D v ) H(Y|A)=\sum_{v\in Values(A)} \dfrac{|D_{v}|}{|D|}H(D_{v}) H(YA)=vValues(A)DDvH(Dv)
其中:

  • V a l u e s ( A ) Values(A) Values(A)是特征 A A A的所有可能取值。
  • D v D_{v} Dv 是特征 A 取值为 v v v 的子集。
  • ∣ D v ∣ ∣ D ∣ \dfrac{|D_{v}|}{|D|} DDv是子集 D v D_{v} Dv 在数据集 D中的权重。
  • H ( D v ) H(D_{v}) H(Dv)是子集 D v D_{v} Dv 的信息熵。

2.3 计算案例

假设我们有一个数据集D,其中包含两个类别(正类和负类)和一个特征X:

A Y
A1 正类
A1 正类
A1 正类
A1 负类
A2 正类
A2 正类
A2 负类
A2 负类
A2 正类
A2 负类
  • 步骤 1:计算整个数据集D的信息熵 H ( D ) H(D) H(D)
    在这里插入图片描述
  • 步骤 2:计算算特征X的条件熵

假设特征 AAA 有两个取值$ {A1, A2}$,我们需要计算每个子集的熵并加权平均:

子集 D A 1 D_{A1} DA1,即 A = A 1 A=A_{1} A=A1条件下的数据集、熵为:

A Y
A1 正类
A1 正类
A1 正类
A1 负类

在这里插入图片描述
子集 D A 2 D_{A2} DA2,即 A = A 2 A=A_{2} A=A2条件下的数据集、熵为:

A Y
A2 正类
A2 正类
A2 负类
A2 负类
A2 正类
A2 负类

在这里插入图片描述

  • 步骤 3:计算条件熵 H ( Y ∣ A ) H(Y|A) H(YA)
    在这里插入图片描述
  • 条件熵的意义

条件熵 H ( Y ∣ A ) H(Y|A) H(YA)表示在知道特征 A的情况下,目标变量 Y的不确定性。条件熵越小,说明特征 A 对目标变量 Y的解释能力越强。因此,在构建决策树时,我们选择条件熵最小的特征进行分裂,从而最大化信息增益。

2.4 代码实现

import math
import pandas as pd
from collections import Counter

def Entropy(DataList):
    '''
        计算随机变量的熵
    '''
    counts = len(DataList)      # 总数量
    counter = Counter(DataList) # 每个变量出现的次数
    prob = {i[0]:i[1]/counts for i in counter.items()}      # 计算每个变量的 p
    H = - sum([i[1]*math.log2(i[1]) for i in prob.items()]) # 计算熵
    
    return H

if __name__ == "__main__":
    # 数据
    data = {
        'A': ['A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2'],
        'target': ['正类', '正类', '正类', '负类', '正类', '正类', '负类', '负类', '正类', '负类']
    }
    # 创建 DataFrame
    df = pd.DataFrame(data)
    
    X = df['A']
    Y = df['target']
    
    XY = list(zip(X,Y))
    HX = Entropy(X)   # 随机变量 X 的熵
    HXY = Entropy(XY) # 联合熵 XY
    HY_X = HXY - HX   # 条件熵  Y|X
    
    print("条件熵:",HY_X)

三、信息增益(Information Gain)

3.1 定义

定义为数据集 D 在特征 A上的熵减少量:
G a i n ( D , A ) = H ( D ) − H ( D ∣ A ) Gain(D,A)=H(D)-H(D|A) Gain(D,A)=H(D)H(DA)
其中:

  • H ( D ) H(D) H(D)为数据集D的熵(即目标变量Y的熵);
  • H ( D ∣ A ) H(D|A) H(DA)为在特征A条件下,目标变量Y的条件熵

G a i n ( D , A ) Gain(D,A) Gain(D,A)值越大,说明数据集 D 在特征 A上的熵减少量越大,进一步说明特征A对于数据集D的重要性越高。

所以,在构建决策树时,选择信息增益最大的特征作为分裂特征。

3.2 计算案例

继续上文条件熵示例。

数据集 D的信息熵 H ( D ) ≈ 0.971 H(D)≈0.971 H(D)0.971,特征 A 的条件熵 H ( D ∣ A ) ≈ 0.924 H(D∣A)≈0.924 H(DA)0.924,则信息增益计算如下:

G a i n ( D , A ) = 0.971 − 0.924 ≈ 0.047 Gain(D,A)=0.971−0.924≈0.047 Gain(D,A)=0.9710.9240.047

四、信息增益率(Information Gain Ratio, IGR)

4.1 定义

信息增益虽然直观,但在处理具有许多取值的特征时,会倾向于选择取值多的特征,因为它们通常会带来较大的信息增益。为了避免这种偏差,引入了信息增益率。
定义如下:
G a i n _ r a t i o ( D , A ) = G a i n ( D , A ) H ( A ) Gain\_ratio(D,A) = \dfrac{Gain(D,A)}{H(A)} Gain_ratio(D,A)=H(A)Gain(D,A)
其中, G a i n ( D , A ) Gain(D,A) Gain(D,A)为特征A在数据集D下的信息增益;

H ( A ) H(A) H(A)为特征A的熵值.

4.2 计算案例

继续上文条件熵示例。

数据集 D的信息熵 H ( D ) ≈ 0.971 H(D)≈0.971 H(D)0.971,特征 A 的条件熵 H ( D ∣ A ) ≈ 0.924 H(D∣A)≈0.924 H(DA)0.924,信息增益 G a i n ( D , A ) = 0.971 − 0.924 ≈ 0.047 Gain(D,A)=0.971−0.924≈0.047 Gain(D,A)=0.9710.9240.047,信息增益率
G a i n _ r a t i o ( D , A ) = G a i n ( D , A ) H ( A ) = 0.047 0.971 Gain\_ratio(D,A) = \dfrac{Gain(D,A)}{H(A)} = \dfrac{0.047}{0.971} Gain_ratio(D,A)=H(A)Gain(D,A)=0.9710.047

4.3 总结

  • 信息增益:度量某个特征对结果分类的不确定性减少的程度。
  • 信息增益率:通过规范化信息增益来减轻对取值多的特征的偏好,选择信息增益率最高的特征来进行决策树的划分。

在实际应用中,决策树算法(如 C4.5)使用信息增益率来选择最优的分割特征,避免信息增益在处理取值较多特征时的偏差问题。

五、基尼系数(Gini coefficient)

Gini 系数(Gini coefficient),也称为基尼系数或基尼指数,是衡量不平等或分布不均衡的一种常用方法。在决策树中,Gini 系数常被用来衡量节点的不纯度,帮助选择最佳的分裂点。

5.1 定义

对于一个包含多个类别的数据集,假设有 K K K 个类别,记为$ {1,2,…,K}$。设 p i p_{i} pi表示类别 i在数据集中的比例(即频率),则 Gini 系数 G i n i ( p ) Gini(p) Gini(p)定义如下:
G i n i ( p ) = 1 − ∑ i = 1 K p i 2 Gini(p)=1-\sum_{i=1}^{K}p_{i}^{2} Gini(p)=1i=1Kpi2
其中, p i p_{i} pi 是类别 i 的频率。Gini 系数的取值范围是 0 ≤ G i n i ( p ) ≤ 0.5 0≤Gini(p)≤0.5 0Gini(p)0.5 ;

所有样本属于同一类别时,Gini 系数达到最小值 0,表示数据集的纯度最高;

样本均匀分布在各个类别时,Gini 系数达到最大值 0.5,表示数据集的纯度最低。

5.2 代码实现

def gini_index(arr):
    '''' 计算基尼系数 '''
    # 如果为空,返回0
    if len(arr) == 0:
        return 0
    
    # 计算每个类别的频率
    unique_values, counts = np.unique(arr, return_counts=True)
    prob = counts / len(arr)
    
    # 计算基尼指数
    gini = 1 - np.sum(prob ** 2)
    
    return gini
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐