使用Python实现ID3算法

实现初衷:学业要求,本想从网上copy,但为了那点可怜的自尊心,花费一个周末写了ID3算法,用了一个周末确实有点菜。

声明:实现该算法时,使用的都是些基本函数,并未设计高深的函数。实现的过程冗余度也很高,没有进行优化也并未达到可以对很多数据进行处理。当然如果想要进行多数据处理,可以再次算法基础上改进一下。全部代码在底部。

需要解决的问题

如图所示

思路

  1. 先对数据进行处理,使用pandas包将数据转化为易处理的数据

  1. 对数据的每一列进行计数,统计每一列的元素出现的个数

  1. 计算信息熵,这也是非常重要的一步,信息熵决定了每个属性判断的先后

  1. 排序选优

  1. 建模型

全部代码如下所示

import math

import pandas as pd
import numpy as np

data = [[0, 2, 0, 0, 0],  # 数据集
        [0, 2, 0, 1, 0],
        [1, 2, 0, 0, 1],
        [2, 1, 0, 0, 1],
        [2, 0, 1, 0, 1],
        [2, 0, 1, 1, 0],
        [1, 0, 1, 1, 1],
        [0, 1, 0, 0, 0],
        [0, 0, 1, 0, 1],
        [2, 1, 1, 0, 1],
        [0, 1, 1, 1, 1],
        [1, 1, 0, 1, 1],
        [1, 2, 1, 0, 1],
        [2, 1, 0, 1, 0]]
data = np.array(data)
df = pd.DataFrame(data)  # 转为df

# 计数
def count(data, a):
    df = pd.DataFrame(data)
    sum = {}
    for i in range(len(df[a].value_counts())):  # 遍历目标列的数据个数
        m1 = df[a].value_counts().values[i]
        sum[i] = m1  # 存储到sum中
    return sum

# 信息熵
def allInformationEntropy(data, a):
    m2 = count(data, a)  #计数
    m3 = len(data)
    ie = 0
    for i in range(len(m2)):  # for循环计算每个项
        ie1 = (m2[i] / m3 * math.log2(m2[i] / m3)) * (-1)
        i += 1
        ie += ie1
    return ie


# 分叉信息熵
# 先将每一列的元素提取出来,在分别提取(去掉其余列,如何进行上述迭代)
def InformationEntropy(data, a):
    df = pd.DataFrame(data)
    ie = 0
    m5 = 0
    for i in range(len(df[a].value_counts())):
        data1 = df[df[a] == i]  # 删除不想要的行
        m2 = count(data1, 4)   #对新的数据最后结果计数
        m3 = len(data1)   #选出来的label的行数
        for j in range(len(m2)):  # for循环计算每个项
            # print(m2[j])
            ie1 = ((m2[j] / m3) * (math.log2(m2[j] / m3))) * (-1)
            j += 1
            ie += ie1
        # print(ie)
        m4 = (m3 / len(data)) * ie
        # print(m4)
        i += 1
        m5 += m4  # 该列总的E
        ie=0
        # print(m5)
    return m5

def Gain(m,n): #m为总的  n 为每个决策
    return m - n


#选优
def best(data):
    a4 = allInformationEntropy(data, 4)
    a3 = InformationEntropy(data, 3)
    a2 = InformationEntropy(data, 2)
    a1 = InformationEntropy(data, 1)
    a0 = InformationEntropy(data, 0)
    g0 = Gain(a4, a0)
    g1 = Gain(a4, a1)
    g2 = Gain(a4, a2)
    g3 = Gain(a4, a3)
    list= [g0,g1,g2,g3]  #0 2 3 1
    return list



def makingDecision(data,test):
    #判断test的列的优先级
    list =best(data)
    list1 = best(data)
    first = max(list)
    firstDecision1 = list1.index(first)
    list.remove(first)

    second = max(list)
    secondDecision1 = list1.index(second)
    list.remove(second)

    three = max(list)
    threeDecision1 = list1.index(three)
    list.remove(three)

    four = max(list)
    fourDecision1 = list1.index(four)


    # list = best(data)
    firstDecision = test[firstDecision1]
    secondDecision = test[secondDecision1]
    threeDecision = test[threeDecision1]
    fourDecision = test[fourDecision1]
    data1 = df[df[firstDecision1] == firstDecision]  #选取第一列 0
    df1 = pd.DataFrame(data1)
    if(df1[4].nunique()!=1):   #用if语句决策 根据信息增益得到各个决策的高低  读取test数据的最优那一列的数据,筛选数据,这样重复得出结果
        data2 = df1[df1[secondDecision1] == secondDecision]  #选取第二列  2
        df2 = pd.DataFrame(data2)
        if(df2[4].nunique()!=1):
            data3 = df2[df2[threeDecision1] == threeDecision]  #选第三列  3
            df3 = pd.DataFrame(data3)
            if (df3[4].nunique() != 1):
                data4 = df3[df3[fourDecision1] == fourDecision]   #选第四列  1
                df4 = pd.DataFrame(data4)
                # print(df4[4].values)
                return df4[4].values.max()
            else:
                # print(df3[4].values)
                return df3[4].values.max()
        else:
            # print(df2[4].values)
            return df2[4].values.max()
    else:
        # print(df1[4].values)
        return df1[4].values.max()

#执行
if __name__ == '__main__':
    test = [0,0,0,1]
    result = makingDecision(data,test)
    # print(result)
    if result == 0:
        print("不买")
    if result == 1:
        print("买")

结果

所有步骤的说明均写在代码中。

本模型并未建树,但是思路和建树大体一样,我也不太清楚算不算建树,每一次test,都是根据已有的分层模型进行处理得出结果。

代码写的并不是很高,如需很高的要求,不建议使用借鉴!

如有问题欢迎留言!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值