解题思路

  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)

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

总结

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