id3决策树 鸢尾花 python_决策树ID3算法之纯手工python实现

"""
这是一个统计程序而不是一个计算程序,针对标称型数据集可以实现多种形式的统计;
可以计算在各个节点上的信息增益(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)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值