3-1 计算给定数据的香农熵
1. 算法思想
(1)计算出总共有多少组数据(返回数据行数)。(2)初始化分类字典和香农熵,其中分类字典初始化为空,香农熵初始化为0。(3)计算所有数据的类别(假定为每行最后一列),将其类别和次数添加到字典中。(4)遍历字典所有的类别,分别计算所有类别出现的概率和香农熵,然后对香农熵进行累加。
2. 计算香农熵的函数代码:
def calcShannonEnt(dataSet):rows = len(dataSet) # 返回数据行数labelCounts = {} # 为所有可能的分类创造字典shannonEnt = 0.0 # 香农熵# 计算所有分类的数目for row_data in dataSet:currentLabel = row_data[-1] # 提取每行数据的类型(最后一列)# 若当前分类不在字典中则将其加入字典,然后数量加1;若存在则直接累加if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1# 计算香农熵for key in labelCounts:prop = float(labelCounts[key]) / rowsshannonEnt -= prop * log2(prop)return shannonEnt
3. 完整代码
from math import log2'''算法思想:(1)计算出总共有多少组数据(返回数据行数)。(2)初始化分类字典和香农熵,其中分类字典初始化为空,香农熵初始化为0。(3)计算所有数据的类别(假定为每行最后一列),将其类别和次数添加到字典中。(4)遍历字典所有的类别,分别计算所有类别出现的概率和香农熵,然后对香农熵进行累加。'''def calcShannonEnt(dataSet):rows = len(dataSet) # 返回数据行数labelCounts = {} # 为所有可能的分类创造字典shannonEnt = 0.0 # 香农熵# 计算所有分类的数目for row_data in dataSet:currentLabel = row_data[-1] # 提取每行数据的类型(最后一列)# 若当前分类不在字典中则将其加入字典,然后数量加1;若存在则直接累加if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1# 计算香农熵for key in labelCounts:prop = float(labelCounts[key]) / rowsshannonEnt -= prop * log2(prop)return shannonEntdef createDataSet():dataSet = [[1, 1, 'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]labels = ['no surfacing', 'flippers']return dataSet, labelsif __name__ == "__main__":dataSet, labels = createDataSet()print(calcShannonEnt(dataSet)) # 0.970950594...