《机器学习实战》第3章决策树程序清单3-1 计算给定数据集的香农熵calcShannonEnt()运行过程...

本文介绍了一种计算数据集信息熵的方法,通过Python实现,展示了如何量化数据集的不确定性,并给出了不同情况下熵的具体计算示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

from math import log

def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    print("样本总数:" + str(numEntries))

    labelCounts = {} #记录每一类标签的数量

    #定义特征向量featVec
    for featVec in dataSet:
        
        currentLabel = featVec[-1] #最后一列是类别标签

        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0;

        labelCounts[currentLabel] += 1 #标签currentLabel出现的次数
        print("当前labelCounts状态:" + str(labelCounts))

    shannonEnt = 0.0

    for key in labelCounts:
        
        prob = float(labelCounts[key]) / numEntries #每一个类别标签出现的概率

        print(str(key) + "类别的概率:" + str(prob))
        print(prob * log(prob, 2) )
        shannonEnt -= prob * log(prob, 2) 
        print("熵值:" + str(shannonEnt))

    return shannonEnt


def createDataSet():
    dataSet = [
        # [1, 1, 'yes'],
        # [1, 0, 'yes'],
        # [1, 1, 'no'],
        # [0, 1, 'no'],
        # [0, 1, 'no'],
        # #以下随意添加,用于测试熵的变化,越混乱越冲突,熵越大
        # [1, 1, 'no'],
        # [1, 1, 'no'],
        # [1, 1, 'no'],
        # [1, 1, 'no'],
        # [1, 1, 'maybe'],
        # [1, 1, 'maybe1']
        # 用下面的8个比较极端的例子看得会更清楚。如果按照这个规则继续增加下去,熵会继续增大。
        # [1,1,'1'],
        # [1,1,'2'],
        # [1,1,'3'],
        # [1,1,'4'],
        # [1,1,'5'],
        # [1,1,'6'],
        # [1,1,'7'],
        # [1,1,'8'],

        # 这是另一个极端的例子,所有样本的类别是一样的,有序,不混乱,此时熵为0
        [1,1,'1'],
        [1,1,'1'],
        [1,1,'1'],
        [1,1,'1'],
        [1,1,'1'],
        [1,1,'1'],
        [1,1,'1'],
        [1,1,'1'],        
    ]

    labels = ['no surfacing', 'flippers']

    return dataSet, labels

def testCalcShannonEnt():

    myDat, labels = createDataSet()
    print(calcShannonEnt(myDat))

if __name__ == '__main__':
    testCalcShannonEnt()
    print(log(0.000002, 2))

 

 

 

以下输出结果是每个样本的类别都不同时的输出结果:

样本总数:8
当前labelCounts状态:{'1': 1}
当前labelCounts状态:{'1': 1, '2': 1}
当前labelCounts状态:{'1': 1, '2': 1, '3': 1}
当前labelCounts状态:{'1': 1, '2': 1, '3': 1, '4': 1}
当前labelCounts状态:{'1': 1, '2': 1, '3': 1, '4': 1, '5': 1}
当前labelCounts状态:{'1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1}
当前labelCounts状态:{'1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1}
当前labelCounts状态:{'1': 1, '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1}
1类别的概率:0.125
-0.375
熵值:0.375
2类别的概率:0.125
-0.375
熵值:0.75
3类别的概率:0.125
-0.375
熵值:1.125
4类别的概率:0.125
-0.375
熵值:1.5
5类别的概率:0.125
-0.375
熵值:1.875
6类别的概率:0.125
-0.375
熵值:2.25
7类别的概率:0.125
-0.375
熵值:2.625
8类别的概率:0.125
-0.375
熵值:3.0
3.0
-18.931568569324174
[Finished in 1.3s]

 

from math import log
def calcShannonEnt(dataSet):numEntries = len(dataSet)print("样本总数:" + str(numEntries))
labelCounts = {} #记录每一类标签的数量
#定义特征向量featVecfor featVec in dataSet:currentLabel = featVec[-1] #最后一列是类别标签
if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0;
labelCounts[currentLabel] += 1 #标签currentLabel出现的次数print("当前labelCounts状态:" + str(labelCounts))
shannonEnt = 0.0
for key in labelCounts:prob = float(labelCounts[key]) / numEntries #每一个类别标签出现的概率
print(str(key) + "类别的概率:" + str(prob))print(prob * log(prob, 2) )shannonEnt -= prob * log(prob, 2) print("熵值:" + str(shannonEnt))
return shannonEnt

def createDataSet():dataSet = [# [1, 1, 'yes'],# [1, 0, 'yes'],# [1, 1, 'no'],# [0, 1, 'no'],# [0, 1, 'no'],# #以下随意添加,用于测试熵的变化,越混乱越冲突,熵越大# [1, 1, 'no'],# [1, 1, 'no'],# [1, 1, 'no'],# [1, 1, 'no'],# [1, 1, 'maybe'],# [1, 1, 'maybe1']# 用下面的8个比较极端的例子看得会更清楚。如果按照这个规则继续增加下去,熵会继续增大。# [1,1,'1'],# [1,1,'2'],# [1,1,'3'],# [1,1,'4'],# [1,1,'5'],# [1,1,'6'],# [1,1,'7'],# [1,1,'8'],
# 这是另一个极端的例子,所有样本的类别是一样的,有序,不混乱,此时熵为0[1,1,'1'],[1,1,'1'],[1,1,'1'],[1,1,'1'],[1,1,'1'],[1,1,'1'],[1,1,'1'],[1,1,'1'],]
labels = ['no surfacing', 'flippers']
return dataSet, labels
def testCalcShannonEnt():
myDat, labels = createDataSet()print(calcShannonEnt(myDat))
if __name__ == '__main__':testCalcShannonEnt()print(log(0.000002, 2))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值