# -*- coding: UTF-8 -*-
from math import log
import pandas as pd
dataSet = pd.read_csv('dataSet.csv', header=None).values.tolist()
# 给定一个数据集,calcInfoEnt可以用于计算一个数据集的信息熵,可直接调用
# 也可不使用,通过自己的方式计算信息增益
def calcInfoEnt(data):
numEntres = len(data)
labelcnt = {} # 用于统计正负样本的个数
for item in data:
if item[-1] not in labelcnt:
labelcnt[item[-1]] = 0
labelcnt[item[-1]] += 1
infoEnt = 0.0
for item in labelcnt: # 根据信息熵的公式计算信息熵
curr_info_entr = float(labelcnt[item]) / numEntres
infoEnt = infoEnt - curr_info_entr * log(curr_info_entr, 2)
return infoEnt
# 返回值 infoEnt 为数据集的信息熵
# 给定一个数据集,用于切分一个子集,可直接用于计算某一特征的信息增益
# 也可不使用,通过自己的方式计算信息增益
# dataSet是要划分的数据集,i 代表第i个特征的索引index
# value对应该特征的某一取值
def create_sub_dataset(dataSet, i, value):
res = []
for item in dataSet:
if item[i] == value:
curr_data = item[:i] + item[i + 1:]
res.append(curr_data)
return res
def calc_max_info_gain(dataSet): # 计算所有特征的最大信息增益,dataSet为给定的数据集
n = len(dataSet[0]) - 1 # n 是特征的数量,-1 的原因是最后一列是分类标签
total_entropy = calcInfoEnt(dataSet) # 整体数据集的信息熵
max_info_gain = [0, 0] # 返回值初始化
# code start here
best_feature=-1
for i in range(n):
featList=[example[i] for example in dataSet]
uniqueVals=set(featList)
newEntropy=0.0
for value in uniqueVals:
subDataSet=create_sub_dataset(dataSet,i,value)
prob=len(subDataSet)/float(len(dataSet))
newEntropy+=prob*calcInfoEnt(subDataSet)
infoGain=total_entropy-newEntropy
if(infoGain>max_info_gain[1]):
max_info_gain[1]=infoGain
max_info_gain[0]=i
best_feature=1
# code end here
return max_info_gain
if __name__ == '__main__':
info_res = calc_max_info_gain(dataSet)
print("信息增益最大的特征索引为:{0},对应的信息增益为{1}".format(info_res[0], info_res[1]))
12-14
908
11-01
1696