题解 | #信用评分模型优化#

信用评分模型优化

https://www.nowcoder.com/practice/27a2c6a4127c4c7080d34fc017d337bc

解题思路

  1. 计算数据集的信息熵:统计信用评分结果中"良好"和"不良"的比例,计算整个数据集的不确定性。
  2. 计算每个特征的信息增益比
    • 对每个特征,统计其不同取值
    • 计算按该特征划分后各子集的信息熵
    • 计算信息增益和分裂信息
    • 得到信息增益比
  3. 选择最佳特征:比较所有特征的信息增益比,选择值最大的特征。

代码解析

import numpy as np

def calculate_entropy(data):
    """计算数据集的信息熵"""
    labels = [record[-1] for record in data]  # 提取所有标签
    label_counts = {}  # 统计各类标签数量
    for label in labels:
        label_counts[label] = label_counts.get(label, 0) + 1
    
    entropy = 0.0
    total = len(labels)
    for count in label_counts.values():
        prob = count / total  # 计算当前类别的概率
        entropy -= prob * np.log2(prob)  # 累加熵值
    return entropy

def split_dataset(data, axis, value):
    """按特征划分数据集"""
    ret_dataset = []
    for record in data:
        if record[axis] == value:  # 匹配特征取值
            # 移除当前特征列
            reduced_record = record[:axis] + record[axis+1:]
            ret_dataset.append(reduced_record)
    return ret_dataset

def calculate_gain_ratio(data, feature):
    """计算指定特征的信息增益比"""
    base_entropy = calculate_entropy(data)  # 原始数据集熵
    feature_values = [record[feature] for record in data]  # 特征取值列表
    unique_vals = set(feature_values)  # 唯一取值集合
    
    new_entropy = 0.0  # 条件熵
    split_info = 0.0   # 分裂信息
    total = len(data)
    
    for value in unique_vals:
        sub_dataset = split_dataset(data, feature, value)  # 划分子集
        prob = len(sub_dataset) / total  # 当前取值概率
        new_entropy += prob * calculate_entropy(sub_dataset)  # 累加条件熵
        
        # 计算分裂信息(避免概率为0)
        if prob > 0:
            split_info -= prob * np.log2(prob)
    
    info_gain = base_entropy - new_entropy  # 信息增益
    
    # 处理分裂信息为0的情况(特征只有单一取值)
    if split_info == 0:
        return 0
    
    gain_ratio = info_gain / split_info  # 信息增益比
    return gain_ratio

def choose_best_feature_to_split(data):
    """选择最佳划分特征"""
    num_features = len(data[0]) - 1  # 特征数量(最后一列为标签)
    best_gain_ratio = 0.0  # 最佳信息增益比
    best_feature = -1      # 最佳特征索引
    
    for i in range(num_features):
        gain_ratio = calculate_gain_ratio(data, i)  # 计算当前特征增益比
        
        # 更新最佳特征
        if gain_ratio > best_gain_ratio:
            best_gain_ratio = gain_ratio
            best_feature = i
            
    return best_feature

# 主程序
data = eval(input())  # 读取二维列表
best_feature = choose_best_feature_to_split(data)
print(best_feature)

关键函数说明

  1. calculate_entropy(data)

    • 输入:数据集(二维列表)
    • 输出:数据集的信息熵
    • 过程:统计标签分布,根据公式计算熵值
  2. split_dataset(data, axis, value)

    • 输入:数据集,特征索引,特征值
    • 输出:划分后的子集(移除当前特征列)
    • 过程:筛选指定特征值的记录,并移除该特征列
  3. calculate_gain_ratio(data, feature)

    • 输入:数据集,特征索引
    • 输出:该特征的信息增益比
    • 过程:
      1. 计算原始熵
      2. 计算条件熵(各子集熵的加权和)
      3. 计算分裂信息
      4. 计算信息增益比 = (原始熵 - 条件熵) / 分裂信息
  4. choose_best_feature_to_split(data)

    • 输入:数据集
    • 输出:最佳特征索引
    • 过程:遍历所有特征,选择信息增益比最大的特征

总结

本题实现了决策树中基于信息增益比的特征选择方法,通过量化特征对分类不确定性的减少程度,选择最有助于信用风险分类的特征。信息增益比通过引入分裂信息,有效解决了信息增益对多值特征的偏好问题,使特征选择更加合理。

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-11 12:31
以前小时候我最痛恨出轨、偷情的人,无论男女,为什么会出轨?现在我成了自己最讨厌的人,没想到分享的东西在牛客会被这么多人看,大家的评价都很中肯,我也认同,想过一一回复,但我还是收声了,我想我应该说说这件事,这件事一直压在我心里,是个很大的心结,上面说了人为什么出轨,我大概能明白了。我们大一下半年开始恋爱,开始恋爱,我给出了我铭记3年的承诺,我对她好一辈子,我永远不会背叛,我责任心太重,我觉得跟了我,我就要照顾她一辈子,我们在一起3年我都没有碰过她,她说往东我就往东,她说什么我做什么,她要我干什么,我就干什么!在学校很美好,中途也出过一些小插曲,比如男闺蜜、男闺蜜2号等等等。但我都强迫她改掉了,我...
牛客刘北:两个缺爱的人是没有办法好好在一起的,但世界上哪有什么是非对错?你后悔你们在一起了,但是刚刚在一起的美好也是真的呀,因为其他人的出现,你开始想要了最开始的自己,你的确对不起自己,21岁的你望高物远,你完全可以不谈恋爱,去过你想要的生活,你向往自由,在一起之后,你要想的不是一个人,而是两个人,你不是变心了,就像你说的,你受够了,你不想包容了,冷静几天是你最优的选择,爱人先爱己。
社会教会你的第一课
点赞 评论 收藏
分享
06-23 11:28
门头沟学院 Java
牛客91966197...:也有可能是点拒绝的时候自动弹的话术
点赞 评论 收藏
分享
酷酷我灵儿帅:这去不去和线不线下面说实话没啥关系
点赞 评论 收藏
分享
07-09 15:55
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务