【机器学习(三)】机器学习中:信息熵,信息增益,信息增益比,原理,案例,代码实现。

目录

引言

原理

信息熵

条件熵

信息增益

信息增益算法流程

信息增益比

案例

信息熵求解

信息增益求解

扫描二维码关注公众号,回复: 11375399 查看本文章

信息增益比求解

结果分析

案例的代码实现


上一篇:【机器学习(二)】K近邻算法:原理、kd树构造和查找、案例分析、代码(机器学习库、自己实现)

引言

在机器学习和深度学习中,经常会用到信息熵(entropy)这个概念,可以理解为熵表示的是随机变量不确定度的衡量。例如概率0.5比概率0.3的不确定度要高。

原理

信息熵

设X是一个取值有限的离散随机变量,其概率分布为:P(X=x_i)=p_i, i=1,2,3,...,n,则随机变量X的熵定义为H(X)=-\sum_{i=1}^{n}p_ilogp_i

通常log取2或者3,得到的熵的单位分别称作比特或纳特。从这就可以知道,熵依赖X的分布,和X的取值无关,所以也可以把X的熵记做H(p):

H(p)=-\sum_{i=1}^{n}p_ilogp_i

当随机变量只有两个取值的时候,例如0,1,那么X的分布为:

P(X=1)=p,P(X=0)=1-p,0\leq p\leq 1

那么X的熵为:

H(p)=-p\log_2p-(1-p)log_2(1-p)

H(p)的变化曲线如下:

从上图中可以看出,当p=0或者1的时候,熵为0,这个时候不确定度最低,因为p=0或1已经决定x属于什么了。

同理,当p=0.5的时候不确定度最高,此时很难分清x到底是什么。

条件熵

设随机变量(X,Y)的联合概率分布为:P(X=x_i,Y=y_i)=p_i_j

条件熵H(Y|X)表示在已知随机变量X的条件下,Y的不确定度,因此H(Y|X)=\sum_{i=1}^{n}p_iH(Y|X=x_i)

这里p_i=P(X=x_i)

当熵和条件熵是有训练数据估计而来的,那么对应的熵和条件熵称为经验熵和经验条件熵。

信息增益

信息增益是表示数据集中某个特征X的信息使类Y的信息的不确定性减少的程度,即特征X让类Y不确定度降低。

特征A对训练数据集D的信息的信息增益g(D,A),定义为集合D的熵H(D)与特征A给定条件下D的条件熵H(D|A)之差

g(D,A)=H(D)-H(D|A)

其中H(D)H(D|A)之差成为互信息

信息增益算法流程

数据集为D;样本容量为|D|,即样本个数。

K为分类个数,|C_k|表示属于类别C_k的样本个数,\sum_{k=1}^{K}|C_k|=|D|

特征A取值有a_1,a_2,...,a_n,根据A的取值,把D划分成n个子集D_1,D_2,...,D_n|D_i|D_i的样本个数,\sum_{i=1}^{n}|D_i|=|D|

子集D_i中属于C_k的样本的集合为D_i_k|D_i_k|D_i_k的样本个数。

输入:训练数据集D和特征A

输出:特征A对数据集D的信息增益g(D,A)

  • 计算数据D的经验熵H(D)=-\sum_{k=1}^{K}\frac{C_k}{D}log_2\frac{C_k}{D}
  • 计算特征A对数据集D的经验条件熵H(D|A)=-\sum_{i=1}^{n}\frac{|D_i|}{|D|}\sum_{k=1}^{K}\frac{|D_i_k|}{|D_i|}log_2\frac{|D_i_k|}{|D_i|}
  • 计算信息增益g(D,A)=H(D)-H(D|A)

信息增益比

有时候以信息增益来划分训练数据集的特征,会存在偏向于选择取值较多的特征问题,使用信息增益比可以对这一个问题进行校正,成文一种更加权衡的选择标准。

特征A对训练数据D的信息增益比g_R(D,A)定义为信息增益g(D,A)与训练数据D关于特征A的值的熵之比:

g_R(D,A)=\frac{g(D,A)}{H_A(D)},其中H_A(D)=-\sum_{i=1}^{n}\frac{|D_i|}{|D|}log_2\frac{|D_i|}{|D|},n是特征A取值的个数。

案例

表中是贷款申请表,最后的类别代表是否给予贷款的分类,求训练集信息熵、信息增益和信息增益比。

信息熵求解

从类别中可以知道,是有9个,否有6个,所以信息熵为0.971:

信息增益求解

这里需要对每个特征分别单独求解,例如信贷特征,有三类。一般、好和非常好分别是:5,6,4。

在一般中,是有1个,否有4个;

在好中,是有4个,否有2个;

在非常好中,是有4个,否有0个。所以计算如下:

信息增益比求解

上面已经计算过信息增益了,因此只需计算特征熵即可,计算如下:

 

结果分析

如果以信息增益为特征选择标准,可以知道房子的权重最大,因此优先选择房子作为首要特征,信贷特征其次。

信息增益比则是对信息增益进行了校正,从结果中可以知道,房子特征依旧是首要特征,但是工资特征其次,而不是信息增益中的信贷。

案例的代码实现

没有使用机器学习库实现:

import numpy as np
import pandas as pd
from math import log

def create_data():
    datasets = [['青年', '否', '否', '一般', '否'],
                ['青年', '否', '否', '好', '否'],
                ['青年', '是', '否', '好', '是'],
                ['青年', '是', '是', '一般', '是'],
                ['青年', '否', '否', '一般', '否'],
                ['中年', '否', '否', '一般', '否'],
                ['中年', '否', '否', '好', '否'],
                ['中年', '是', '是', '好', '是'],
                ['中年', '否', '是', '非常好', '是'],
                ['中年', '否', '是', '非常好', '是'],
                ['老年', '否', '是', '非常好', '是'],
                ['老年', '否', '是', '好', '是'],
                ['老年', '是', '否', '好', '是'],
                ['老年', '是', '否', '非常好', '是'],
                ['老年', '否', '否', '一般', '否'],
                ]
    labels = [u'年龄', u'有工作', u'有自己的房子', u'信贷情况', u'类别']
    # 返回数据集和每个维度的名称
    return datasets, labels


# 熵
def calc_ent(datasets):
    data_length = len(datasets)
    label_count = {}
    for i in range(data_length):
        label = datasets[i][-1]
        if label not in label_count:
            label_count[label] = 0
        label_count[label] += 1
    ent = -sum([(p / data_length) * log(p / data_length, 2) for p in label_count.values()])
    return ent


# 经验条件熵
def cond_ent(datasets, axis=0):
    data_length = len(datasets)
    feature_sets = {}
    for i in range(data_length):
        feature = datasets[i][axis]
        if feature not in feature_sets:
            feature_sets[feature] = []
        feature_sets[feature].append(datasets[i])
    cond_ent = sum([(len(p) / data_length) * calc_ent(p) for p in feature_sets.values()])
    return cond_ent


# 信息增益
def info_gain(ent, cond_ent):
    return ent - cond_ent


def info_gain_train(datasets):
    count = len(datasets[0]) - 1
    ent = calc_ent(datasets)
    best_feature = []
    for c in range(count):
        c_info_gain = info_gain(ent, cond_ent(datasets, axis=c))
        best_feature.append((c, c_info_gain))
        print('特征({}) - info_gain - {:.3f}'.format(labels[c], c_info_gain))
    # 比较大小
    best_ = max(best_feature, key=lambda x: x[-1])
    return '特征({})的信息增益最大,选择为根节点特征'.format(labels[best_[0]])

datasets, labels = create_data()
train_data = pd.DataFrame(datasets, columns=labels)
print(train_data)
print('特征信息增益为:', info_gain_train(np.array(datasets)))

结果如下:(值计算了信息增益)

程序运算结果与手动计算结果一致。

下一篇:【机器学习(四)】决策树、ID3算法、C4.5算法、CART算法:原理,案例和代码

---------------------------------------------------------------------------------------------------------------------------------------

更新2020-6-17,将信息增益图中错误的地方改正,对代码进行简化。

猜你喜欢

转载自blog.csdn.net/qq_39709813/article/details/106690860