"""
这是一个统计程序而不是一个计算程序,针对标称型数据集可以实现多种形式的统计;
可以计算在各个节点上的信息增益(gain information),以及统计字典,之后的画图工作我无法实现,在实际运用时
你可以借助该程序计算所有ID3算法需要的信息,然后使用别的画图软件绘制决策树.
如果你拿到的数据集的目标变量不是该例中的‘yes’,‘no’,那么你可以自己替换,
此外把程序75,76行的空字典YES,NO换掉即可
"""
print(__doc__)
from collections import OrderedDict
from math import *
def D_shannon(dataSet):
numEntries = len(dataSet)
labelCounts = {} #有问题,空字典
for featVec in dataSet:
currentLabel = featVec[-1] #取得最后一列数据,该属性取值情况有多少个
if currentLabel not in labelCounts.keys(): #键
labelCounts[currentLabel] = 0 #如果 currentLabel不在字典的建中,就给原来空字典添加一个新的键,宁且给这个键提供一个值0;这是搭建初始字典方法
labelCounts[currentLabel]+=1
print("n目标变量的分类情况:",labelCounts)
shannonEnt = 0.0
sumshannon=[]
for key in labelCounts:
prob = float(labelCounts[key])/numEntries
shannonEnt = -prob*log(prob,2)
sumshannon.append(shannonEnt)
global HD #声明HD为全局变量,这样可以在gain_information()中调用
HD=sum(sumshannon)
print("数据集总的信息熵: ",HD)
def HDA(dataSet,j): #j是数据集的列索引
labelCounts = {} #有问题,空字典
"""创建出每一列变量分类情况的字典"""
for featVec in dataSet:
currentLabel = featVec[j]
if currentLabel not in labelCounts.keys(): #键
labelCounts[currentLabel] = 0
labelCounts[currentLabel]+=1
print("第"+str(j+1)+"个变量的分类情况:",labelCounts)
K,V=[],[]
class0=[]
labelCounts=OrderedDict(labelCounts)
for k,v in labelCounts.items(): #labelCounts是"第"+str(j+1)+"个变量的分类情况:"
K.append(k)
V.append(v)
for line in dataSet:
if line[j]==k and (line[-1]=='yes' or line[-1]=='no'): #这个真牛逼
class0.append(line)
#print(class0)
class1=class0[:] #创建class0的副本,接下来我会删除class0
#print("n第"+str(j+1)+"个变量的"+k+"类",class0[:v])
del class0[:v] #不删除的话,会重复对class0的前几个切片
#print('class1',class1)
labelCounts={}
for featVec in class1[:v]:
currentLabel = featVec[-1] #currentLabel = featVec[j]
if currentLabel not in labelCounts.keys(): #键
labelCounts[currentLabel] = 0
labelCounts[currentLabel]+=1
print("第"+str(j+1)+"个变量的"+str(k)+"类的分类情况统计字典",labelCounts)
YES=[]
NO=[]
hda=[] #后面用于求和的列表
numEntries=len(dataSet)
for line in dataSet:
if line[-1]=='yes': #如果换成别的数据集,需要把目标变量的分类情况(YES/NO)改变一下就行别的不用变
YES.append(line)
if line[-1]=='no':
NO.append(line)
labelCounts = {}
for featVec in YES:
currentLabel = featVec[j] #取得索引j的数据,该属性取值情况有多少个
if currentLabel not in labelCounts.keys(): #键
labelCounts[currentLabel] = 0 #如果 currentLabel不在字典的建中,就给原来空字典添加一个新的键,宁且给这个键提供一个值0;这是搭建初始字典方法
labelCounts[currentLabel]+=1
print("第"+str(j+1)+"个变量下YES的分类情况:",labelCounts)
for i in range(len(K)):
labelCounts=OrderedDict(labelCounts)
for m,n in labelCounts.items():
if m==K[i]:
w=V[i]/numEntries
h=-w*(n/V[i] * log2(n/V[i]))
hda.append(h)
labelCounts = {}
for featVec in NO:
currentLabel = featVec[j] #取得第一列数据,该属性取值情况有多少个
if currentLabel not in labelCounts.keys(): #键
labelCounts[currentLabel] = 0 #如果 currentLabel不在字典的建中,就给原来空字典添加一个新的键,宁且给这个键提供一个值0;这是搭建初始字典方法
labelCounts[currentLabel]+=1
print("第"+str(j+1)+"个变量下NO的分类情况:",labelCounts)
for i in range(len(K)):
labelCounts=OrderedDict(labelCounts)
for m,n in labelCounts.items():
if m==K[i]:
w=V[i]/numEntries
h=-w*(n/V[i] * log2(n/V[i]))
hda.append(h)
global s #声明s为全局变量,这样可以在gain_information()中调用
s=sum(hda)
print("第"+str(j+1)+"个变量的条件熵; ",s)
"""
计算信息增益"""
def gain_information(dataSet,j):
global gain,G
G=[]
D_shannon(dataSet)
HDA(dataSet,j)
gain = HD-s
G.append(gain)
print("第"+str(j+1)+"个变量的信息增益; ",gain)
"""dataSet = [['晴','热','高','弱','no'],
['晴','热','高','强','no'],
['多云','热','高','弱','yes'],
['雨','温和','高','弱','yes'],
['雨','凉爽','正常','弱','yes'],
['雨','凉爽','正常','强','no'],
['多云','凉爽','正常','强','yes'],
['晴','温和','高','弱','no'],
['晴','凉爽','正常','弱','yes'],
['雨','温和','正常','弱','yes'],
['晴','温和','正常','强','yes'],
['多云','温和','高','强','yes'],
['多云','热','正常','弱','yes'],
['雨','温和','高','强','no']]
labels = ['天气','温度','湿度','风力']
"""
dataSet = [['热','高','弱','no'],
['热','高','强','no'],
['热','高','弱','yes'],
['温和','高','弱','yes'],
['凉爽','正常','弱','yes'],
['凉爽','正常','强','no'],
['凉爽','正常','强','yes'],
['温和','高','弱','no'],
['凉爽','正常','弱','yes'],
['温和','正常','弱','yes'],
['温和','正常','强','yes'],
['温和','高','强','yes'],
['热','正常','弱','yes'],
['温和','高','强','no']]
labels = ['天气','温度','湿度','风力']
"""
创建一个for 循环用来计算所有变量的信息增益
"""
for a in range(3): #用a代替认为输入各列的索引
gain_information(dataSet,a)
id3决策树 鸢尾花 python_决策树ID3算法之纯手工python实现
最新推荐文章于 2024-02-21 21:24:39 发布