以香农熵为基础选择最佳特征

来源:互联网 发布:战网网络问题 编辑:程序博客网 时间:2024/06/06 09:01
#coding=utf-8from math import logdef create_data():    #'''创建样本'''    data=[[1,1,'Y'],          [1,1,'Y'],          [1,0,'N'],          [0,1,'N'],          [0,1,'N'],          ]    labels=['no surfacing','flippers']    return data,labelsdef shannon_entropy(data):    """计算香农熵"""    enteries=len(data)    #样本总数    label_count={}    #创建字典用来统计类别出现的频率    for v in data:        #遍历样本        current_label=v[-1]        #获取当前类别        if current_label not in label_count.keys():            label_count[current_label]=0            #判断当前类别是否在字典中,不在的话计数为0        label_count[current_label]+=1        #对类别计数    entropy=0.0    #初始熵为0    for key in label_count:        #遍历字典        prob=float(label_count[key])/enteries        #计算各类类别在样本总数中出现的概率        entropy-=prob*log(prob,2)        #计算香农熵,公式:H(x)=P(x)log2P(x) 以2为底的对数    return entropydef split_data(data,axis,value):    """根据某一特征划分数据"""    ret_data=[]    #结果列表    for v in data:        #遍历样本        if v[axis]==value:            #v[axis]样本中第axis的特征,value 预期的特征值            reduced_v=v[:axis]            #样本前axis个值            reduced_v.extend(v[axis+1:])            #样本后axis个值            ret_data.append(reduced_v)            #得到的结果就是除选定的特征外样本中其他的值            #根据需求可返回不同的结果。比如我只想根据axis=1这个条件返回Y or N这个结果            #reduced_v=v[axis+1:] ... ret_data.append(reduced_v) 或者            #单成一个列表 ret_data.extend(v[axis+1:])    return ret_datadef best_split_feature(data):    """选择最佳特征  即 最小熵 """    feature_number=len(data[0])-1    #获取特征数目。即,这组数据有几个特征    base_entropy=shannon_entropy(data)    #以样本的香农熵为基础熵    best_entropy=0.0;best_feature=-1    #初始化最佳熵和最佳特征。这个best_feature定义的常量应该是随意的。    for i in range(feature_number):        #遍历特征        feature_list=[example[i] for example in data]        #特征列表。i=0时,就是每个样本第一个特征所构成的列表        unique_value=set(feature_list)        #剔除特征列表列表中的重复值        new_entropy=0.0        #设定新熵为0        for value in unique_value:            #遍历具有唯一性的特征列表            sub_data=split_data(data,i,value)            #根据唯一的特征划分数据            prob=len(sub_data)/float(len(data))            #计算按各特征划分后所占数据总量的比例            new_entropy+=prob*shannon_entropy(sub_data)            #计算香农熵        info=base_entropy-new_entropy        #基础熵-新熵        if (info > best_entropy):            best_entropy=info            #对比,传值            best_feature=i    return best_feature        

0 0