信息熵计算程序[Python+CSV格式数据集]

cnblogs 2024-08-28 14:13:00 阅读 73

0 前言

  • 为了便于学习决策树信息熵相关知识,笔者编写了一个专门用于计算变量信息熵、条件熵、信息增益、信息增益比的程序,方便提升学习效率。
  • 程序中包含了计算过程的数据和详细信息以及最终计算结果。
  • 编程语言为Python,搭配CSV数据格式使用。

1 数据集

1.1 游玩数据集

根据天气状况判断是否出去玩。

  • 属性id表示每个样本的编号。
  • 属性outlook表示户外天气。sunny晴天,overcast阴天,rainy雨天。
  • 属性temperature表示温度,hot热,mild温暖,cool冷。
  • 属性humidity表示湿度。high高,normal正常。
  • 属性windy表示是否有风。not没有,yes有。
  • 属性play表示是否出去玩。yes出去玩,no不出去玩。

数据集如下图(1-1)所示。

image

点击查看游玩.CSV

<code>id,outlook,temperature,humidity,windy,play

1,sunny,hot,high,not,no

2,sunny,hot,high,yes,no

3,overcast,hot,high,not,yes

4,rainy,mild,high,not,yes

5,rainy,cool,normal,not,yes

6,rainy,cool,normal,yes,no

7,overcast,cool,normal,yes,yes

8,sunny,mild,high,not,no

9,sunny,cool,normal,not,yes

10,rainy,mild,normal,not,yes

11,sunny,mild,normal,yes,yes

12,overcast,mild,high,yes,yes

13,overcast,hot,normal,not,yes

14,rainy,mild,high,yes,no

1.2 西瓜数据集

该数据集来源于西瓜书上,如下图(1-2)所示。

根据西瓜的特征等判断是否是好瓜。

image

点击查看西瓜.CSV

<code>编号,色泽,根蒂,敲声,纹理,脐部,触感,好瓜

1,青绿,蜷缩,浊响,清晰,凹陷,硬滑,是

2,乌黑,蜷缩,沉闷,清晰,凹陷,硬滑,是

3,乌黑,蜷缩,浊响,清晰,凹陷,硬滑,是

4,青绿,蜷缩,沉闷,清晰,凹陷,硬滑,是

5,浅白,蜷缩,浊响,清晰,凹陷,硬滑,是

6,青绿,稍蜷,浊响,清晰,稍凹,软粘,是

7,乌黑,稍蜷,浊响,稍糊,稍凹,软粘,是

8,乌黑,稍蜷,浊响,清晰,稍凹,硬滑,是

9,乌黑,稍蜷,沉闷,稍糊,稍凹,硬滑,否

10,青绿,硬挺,清脆,清晰,平坦,软粘,否

11,浅白,硬挺,清脆,模糊,平坦,硬滑,否

12,浅白,蜷缩,浊响,模糊,平坦,软粘,否

13,青绿,稍蜷,浊响,稍糊,凹陷,硬滑,否

14,浅白,稍蜷,沉闷,稍糊,凹陷,硬滑,否

15,乌黑,稍蜷,浊响,清晰,稍凹,软粘,否

16,浅白,蜷缩,浊响,模糊,平坦,硬滑,否

17,青绿,蜷缩,沉闷,稍糊,稍凹,硬滑,否

1.3 贷款数据集

该数据集来源于统计学习方法,数据如下图(1-3)所示。

根据一个人的家庭经济等条件判断是否要贷款给这个人,类别为是表示同意给此人贷款。反之不同意给此人贷款。

image

点击查看贷款.CSV

<code>id,年龄,有工作,有房子,信贷情况,类别

1,青年,否,否,一般,否

2,青年,否,否,好,否

3,青年,是,否,好,是

4,青年,是,是,一般,是

5,青年,否,否,一般,否

6,中年,否,否,一般,否

7,中年,否,否,好,否

8,中年,是,是,好,是

9,中年,否,是,非常好,是

10,中年,否,是,非常好,是

11,老年,否,是,非常好,是

12,老年,否,是,好,是

13,老年,是,否,好,是

14,老年,是,否,非常好,是

15,老年,否,否,一般,否

2 程序解读

程序函数解读如下图(2-1)所示,从上至下浏览。

image

3 运行结果解读

此处笔者使用了西瓜数据集。

<code>data = pd.read_csv('./Datasets/信息熵/西瓜.csv')

运行结果如下图(2-2)所示。

image

4 程序源代码

点击查看代码

<code>import numpy as np

import pandas as pd

#获取信息熵 H(play)

# #data:df col:play show:是否信息计算信息

def get_information_entropy(data,col,show=False):

#获取col列列名

str_col_names = data.columns.values

col=str_col_names[col]

i_cnt=data.shape[0] #总行数

if show==True:

print('数据总样本:{}个'.format(i_cnt),end='\t')code>

df_end_uni=np.unique(data[col].values) #最后一列去重 ['no' 'yes']

arr_uni_cnt=np.array([],dtype=np.int32) #保存去重后每一个col的个数 [12,12]

for s in df_end_uni:

df_filter=data[data[col]==s]

arr_uni_cnt=np.append(arr_uni_cnt,df_filter.shape[0])

if show == True:

print('{}=\'{}\'有{}个 '.format(col,s,df_filter.shape[0]),end='')code>

if show == True:

print('\nH({})='.format(col),end='')code>

for i in arr_uni_cnt:

print('-({}/{})log2({}/{})'.format(i,i_cnt,i,i_cnt),end='')code>

arr_uni_cnt=arr_uni_cnt/i_cnt

arr_uni_cnt=arr_uni_cnt*np.log2(arr_uni_cnt)

f_res=np.sum(arr_uni_cnt*-1)

if show == True:

print('={:.4f}'.format(f_res),end='\n\n')code>

return f_res

#获取data第c1列等于s1条件下c2列等于s2的个数 及 data第c1列等于s1条件下的个数

def counter(data,c1,s1,c2,s2):

df_filter1 = data[data[c1] == s1]

df_filter2 = df_filter1[df_filter1[c2] == s2]

return df_filter2.shape[0],df_filter1.shape[0]

def calculater(arr_val):

arr_res=np.array([])

for a in range(0,len(arr_val),2):

v1=0

if arr_val[a]==0 or arr_val[a]==arr_val[a+1]:

v1=0

else:

v1=-(arr_val[a]/arr_val[a+1]) * np.log2(arr_val[a]/arr_val[a+1])

arr_res=np.append(arr_res,v1)

return np.sum(arr_res)

#某一列条件熵 H(play|outlook=sunny)

# # col表示outlook key表示play show:是否显示计算信息

def get_conditional_entropy(data,col,key,show=False):

i_total=data.shape[0]

str_col_names=data.columns.values #['id' 'overlook' 'temperature' 'humidity' 'windy' 'play']

df_end_uni = np.unique(data[str_col_names[key]].values) # 最后一列去重 ['no' 'yes']

df_col_uni = np.unique(data[str_col_names[col]].values) # 某一列去重 ['overcast' 'rainy' 'sunny']

str_key=str_col_names[key]

dict_single_item={}

for a in df_col_uni:

dict_single_item[a]=np.array([])

for s in df_col_uni: #在outlook=overcast条件下

arr_temp=np.array([])

for ss in df_end_uni:#play=no

cnt,sample=counter(data,str_col_names[col],s,str_col_names[key],ss)

if show == True:

print('当{}=\'{}\'时,样本有{}个,{}=\'{}\'有{}个'.format(str_col_names[col],s,sample,str_col_names[key],ss,cnt))

arr_temp=np.append(arr_temp,[cnt,sample])

dict_single_item[s]=arr_temp

if show == True:

print('H({}|{}=\'{}\')='.format(str_key,str_col_names[col],s),end='')code>

for a in range(0,len(arr_temp),2):

print('-({}/{})log2({}/{})'.format(arr_temp[a],arr_temp[a+1],arr_temp[a],arr_temp[a+1]),end='')code>

print('={:.4f}\n'.format(calculater(arr_temp)))

if show == True:

print('H({}|{})='.format(str_key,str_col_names[col]),end='')code>

i_idx=0

i_idx_end=len(dict_single_item)

i_sum=0

for k in dict_single_item:

arr_val=dict_single_item[k]

if show == True:

print('({}/{})*{:.4f}'.format(arr_val[1],i_total,calculater(arr_val)),end='')code>

i_sum+=(arr_val[1]/i_total)*calculater(arr_val)

if show == True:

if i_idx<i_idx_end-1:

print('+',end='')code>

else:

print('={:.4f}'.format(i_sum),end='\n')code>

i_idx+=1

return i_sum

#获取信息增益 g(D,A)=H(D)-H(D|A)

#data:df key:D col:A show:是否显示计算信息

def get_information_gain(data,key,col,show=False):

f_ie=get_information_entropy(data,key,False)

f_ce=get_conditional_entropy(data,col,key,False)

str_col_names = data.columns.values

str_key = str_col_names[key]

str_col = str_col_names[col]

f_ig=f_ie-f_ce

if show == True:

print('g({},{})=H({})-H({}|{})={:.4f}-{:.4f}={:.4f}\n'.format(

str_key,str_col,str_key,str_key,str_col,f_ie,f_ce,f_ig)

)

return f_ig

#获取信息增益比 gr(play,outlook)= g(play,outlook) / Ha(play)

# data:df key:play col:outlook show:是否显示计算信息

def get_information_gain_ratio(data,key,col,show=False):

str_col_names = data.columns.values

str_key=str_col_names[key]

str_col=str_col_names[col]

f_ig=get_information_gain(data,key,col,False)

f_ie=get_information_entropy(data,key,False)

f_igr=f_ig/f_ie

if show == True:

print('gr({},{})=g({},{}) / H({})={:.4f}/{:.4f}={:.4f}\n'.format(

str_key,str_col,str_key,str_col,str_col,f_ig,f_ie,f_igr)

)

return f_igr

if __name__ == '__main__':

data = pd.read_csv('./Datasets/信息熵/西瓜.csv')

i_key = data.shape[1]-1 # 最终判别特征索引 默认最后一列

#获取每个特征的信息熵、条件熵、信息增益、信息增益比

for i_col in range(1,data.shape[1],1):

print('-'*100)

f_ie_col=get_information_entropy(data,i_col,True)

f_ce_col=get_conditional_entropy(data,i_col,i_key,True)

f_ig_col=get_information_gain(data,i_key,i_col,True)

f_igr_col=get_information_gain_ratio(data,i_key,i_col,True)

5 结语

如有错误请指正,禁止商用。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。