解题思路
- 计算数据集的信息熵:统计信用评分结果中"良好"和"不良"的比例,计算整个数据集的不确定性。
- 计算每个特征的信息增益比:
- 对每个特征,统计其不同取值
- 计算按该特征划分后各子集的信息熵
- 计算信息增益和分裂信息
- 得到信息增益比
- 选择最佳特征:比较所有特征的信息增益比,选择值最大的特征。
代码解析
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)
关键函数说明
-
calculate_entropy(data)
:- 输入:数据集(二维列表)
- 输出:数据集的信息熵
- 过程:统计标签分布,根据公式计算熵值
-
split_dataset(data, axis, value)
:- 输入:数据集,特征索引,特征值
- 输出:划分后的子集(移除当前特征列)
- 过程:筛选指定特征值的记录,并移除该特征列
-
calculate_gain_ratio(data, feature)
:- 输入:数据集,特征索引
- 输出:该特征的信息增益比
- 过程:
- 计算原始熵
- 计算条件熵(各子集熵的加权和)
- 计算分裂信息
- 计算信息增益比 = (原始熵 - 条件熵) / 分裂信息
-
choose_best_feature_to_split(data)
:- 输入:数据集
- 输出:最佳特征索引
- 过程:遍历所有特征,选择信息增益比最大的特征
总结
本题实现了决策树中基于信息增益比的特征选择方法,通过量化特征对分类不确定性的减少程度,选择最有助于信用风险分类的特征。信息增益比通过引入分裂信息,有效解决了信息增益对多值特征的偏好问题,使特征选择更加合理。