列表

详情


AI3. 决策树的生成与训练-信息熵的计算

描述

决策树是非常经典的机器学习模型,以决策树为基模型的集成学习模型(XGBoost、GBDT 等)在工业界得到了极为广泛的应用。决策树有三种常见的启发式生成标准,信息增益就是其中之一。计算某一特征的信息增益主要分为两步,第一步是计算数据集的信息熵,信息熵可以表示为,其中代表的是属于某一类的样本个数,D 是整个数据集的样本数量,K 为类别数量。第二步是根据信息熵计算每个特征的经验条件熵。特征的信息增益即为信息熵和经验条件熵的差。现有一数据集,有 4 个特征,分别为教育程度、是否有车、是否有正式工作和征信情况,通过这 4 个特征决策是否予以审批信用卡,数据已经通过 dataSet 给出。其中 dataSet 每行的前 4 列依次代表上述特征的取值,最后一列代表对应的 label 标签。
要求实现 calcInfoEnt 功能,数据集从当前路径下 dataSet.csv读取,计算在给定数据集的情况下,数据集的信息熵,信息熵用 infoEnt 进行表示,数据类型为 float,将 infoEnt 作为函数返回值。计算逻辑参考题目描述中给出的公式。
其中dataSet.csv的示例数据集如下所示:

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python 3 解法, 执行用时: 796ms, 内存消耗: 524288KB, 提交时间: 2022-07-05

# -*- coding: UTF-8 -*-
from math import log
import pandas as pd

dataSet = pd.read_csv('dataSet.csv', header=None).values.tolist()


def calcInfoEnt(dataSet):
    numEntres = len(dataSet)
    #code start here
    numEntries = len(dataSet) #数据集大小
    labelCounts = {}
    for featVec in dataSet:   #
        currentLabel = featVec[-1]   #获取分类标签
        if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0 #字典值不等于0???
        labelCounts[currentLabel] += 1  #每个类中数据个数统计
    infoEnt = 0.0
    for key in labelCounts:  #信息熵计算
        prob = float(labelCounts[key])/numEntries
        infoEnt -= prob * log(prob,2) 

    return infoEnt
    #code end here
    #返回值 infoEnt 为数据集的信息熵,表示为 float 类型
    
if __name__ == '__main__':
    print(calcInfoEnt(dataSet))
    #输出为当前数据集的信息熵

Python 3 解法, 执行用时: 808ms, 内存消耗: 524288KB, 提交时间: 2022-06-25

# -*- coding: UTF-8 -*-
from math import log
import pandas as pd

dataSet = pd.read_csv('dataSet.csv', header=None).values.tolist()


def calcInfoEnt(dataSet):
    numEntres = len(dataSet)
    #code start here
    labelcnt={}#用于统计正负样本的个数,本例下,统计完成以后labelcnt={'0':6, '1':9}
    for item in dataSet:
        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
    #code end here
    #返回值 infoEnt 为数据集的信息熵,表示为 float 类型
    
if __name__ == '__main__':
    print(calcInfoEnt(dataSet))
    #输出为当前数据集的信息熵

Python 3 解法, 执行用时: 816ms, 内存消耗: 524288KB, 提交时间: 2022-07-07

from collections import Counter
import numpy as np
import pandas as pd

dataSet = pd.read_csv('dataSet.csv', header=None).values[:, -1]


def calcInfoEnt(dataSet):
    numEntres = len(dataSet)
    cnt = Counter(dataSet)  # 计数每个值出现的次数
    probability_lst = [1.0 * cnt[i] / numEntres for i in cnt]
    return -np.sum([p * np.log2(p) for p in probability_lst])


if __name__ == '__main__':
    print(calcInfoEnt(dataSet))

Python 3 解法, 执行用时: 816ms, 内存消耗: 524288KB, 提交时间: 2022-06-27

# -*- coding: UTF-8 -*-
from math import log
import pandas as pd

dataSet = pd.read_csv('dataSet.csv', header=None).values.tolist()


def calcInfoEnt(dataSet):
    numEntres = len(dataSet)
    #code start here
    labelcnt = {}
    for item in dataSet:
        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
    #code end here
    #返回值 infoEnt 为数据集的信息熵,表示为 float 类型
    
if __name__ == '__main__':
    print(calcInfoEnt(dataSet))
    #输出为当前数据集的信息熵

Python 3 解法, 执行用时: 827ms, 内存消耗: 524288KB, 提交时间: 2022-07-21

# -*- coding: UTF-8 -*-
from math import log
import pandas as pd

dataSet = pd.read_csv('dataSet.csv', header=None).values.tolist()


def calcInfoEnt(dataSet):
    numEntres = len(dataSet)
    #code start here
    labelcnt = {} #用于统计正负样本的个数
    for item in dataSet:
        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
    #code end here
    #返回值 infoEnt 为数据集的信息熵,表示为 float 类型
    
if __name__ == '__main__':
    print(calcInfoEnt(dataSet))
    #输出为当前数据集的信息熵

上一题