决策树特征选择实战:用信息增益帮你选出‘最佳提问’(Python/Sklearn版)

发布时间:2026/6/3 7:37:07

决策树特征选择实战:用信息增益帮你选出‘最佳提问’(Python/Sklearn版) 决策树特征选择实战用信息增益帮你选出‘最佳提问’Python/Sklearn版想象一下你在玩二十问游戏目标是猜出对方心里想的明星。每次提问都像在决策树的分支上做选择——是男演员吗获得过奥斯卡吗每个问题的价值取决于它能帮你排除多少错误选项。这正是决策树算法中信息增益的核心思想通过量化每个特征消除不确定性的能力帮我们找到最有价值的提问方式。在机器学习领域特征选择直接影响模型效果。本文将用Python带你从零实现信息增益计算并用Sklearn验证结果。我们会用泰坦尼克号数据集作为实战案例看看哪些特征如性别、舱位等级对预测乘客生存率最有价值。1. 信息熵不确定性的度量标准1948年香农将热力学中的熵引入信息论用它衡量系统的不确定性。在决策树中熵表示数据集的混乱程度熵为0数据集完全纯净如所有乘客都生存熵为1二进制分类时正负样本各占50%不确定性最大计算信息熵的数学公式为import numpy as np def entropy(labels): _, counts np.unique(labels, return_countsTrue) probabilities counts / len(labels) return -np.sum(probabilities * np.log2(probabilities))举个简单例子# 纯净数据集 print(entropy([0, 0, 0])) # 输出0.0 # 完全不确定的数据集 print(entropy([0, 1, 0, 1])) # 输出1.0注意log以2为底是为了让二进制分类的最大熵正好为12. 条件熵与信息增益的计算信息增益衡量的是知道某个特征后标签不确定性减少的程度。计算分三步计算原始数据集熵H(Y)按特征取值划分数据集后计算条件熵H(Y|X)信息增益 H(Y) - H(Y|X)用泰坦尼克号数据中的性别特征举例性别生存死亡总计男性109468577女性23381314计算过程# 总熵 total_entropy entropy([0]*577 [1]*314) # 假设0表示死亡 # 性别为男时的熵 male_entropy entropy([0]*468 [1]*109) # 性别为女时的熵 female_entropy entropy([0]*81 [1]*233) # 条件熵 cond_entropy (577/891)*male_entropy (314/891)*female_entropy # 信息增益 info_gain total_entropy - cond_entropy print(f性别特征的信息增益: {info_gain:.4f})典型输出结果性别特征的信息增益: 0.21773. 实战从零实现特征选择让我们用Python完整实现一个特征选择器。使用泰坦尼克号数据集可通过seaborn库加载import seaborn as sns from sklearn.model_selection import train_test_split # 加载数据 titanic sns.load_dataset(titanic) data titanic[[sex, class, age, fare, survived]].dropna() X data.drop(survived, axis1) y data[survived] # 预处理 X[sex] X[sex].map({male:0, female:1}) X[class] X[class].map({Third:0, Second:1, First:2}) X[age] pd.cut(X[age], bins5).cat.codes # 年龄分箱定义信息增益计算函数def information_gain(X, y, feature): # 计算总熵 total_entropy entropy(y) # 计算特征各取值的加权熵 values, counts np.unique(X[feature], return_countsTrue) weighted_entropy 0 for v, c in zip(values, counts): subset y[X[feature] v] weighted_entropy (c/len(X)) * entropy(subset) return total_entropy - weighted_entropy测试各特征的信息增益for feature in X.columns: gain information_gain(X, y, feature) print(f{feature:8}: {gain:.4f})输出示例sex: 0.2177 class: 0.0982 age: 0.0624 fare: 0.0831结果显示性别是最有预测力的特征这与历史事实一致——妇女儿童优先的救援政策使性别成为生存的关键因素。4. 与Scikit-learn的结果验证为了验证我们的实现是否正确用Sklearn的决策树计算特征重要性from sklearn.tree import DecisionTreeClassifier from sklearn.preprocessing import OneHotEncoder from sklearn.compose import ColumnTransformer # 预处理分类变量 preprocessor ColumnTransformer( transformers[ (cat, OneHotEncoder(), [sex, class]) ], remainderpassthrough ) # 训练决策树 model DecisionTreeClassifier(criterionentropy, max_depth3) X_processed preprocessor.fit_transform(X) model.fit(X_processed, y) # 获取特征重要性 importance model.feature_importances_ features preprocessor.get_feature_names_out() for name, score in zip(features, importance): print(f{name:15}: {score:.4f})输出结果类似cat__sex_0: 0.6934 cat__sex_1: 0.0000 cat__class_0: 0.0000 cat__class_1: 0.0000 cat__class_2: 0.0000 remainder__age: 0.1543 remainder__fare: 0.1523虽然数值表现形式不同但趋势与我们的手动计算结果一致——性别相关特征的重要性最高。细微差异源于Sklearn使用Gini系数变体计算重要性决策树会考虑特征组合效应我们的实现没有处理连续值分箱的优化5. 高级应用与注意事项在实际项目中应用信息增益时需要注意以下问题连续值处理直接计算连续特征的信息增益可能得到误导性结果解决方案先离散化等宽/等频分箱、聚类等# 等频分箱示例 X[fare_bin] pd.qcut(X[fare], q5, labelsFalse) print(information_gain(X.assign(fareX[fare_bin]), y, fare))过拟合风险信息增益倾向于选择取值多的特征改进方法使用信息增益比考虑特征本身的熵def information_gain_ratio(X, y, feature): gain information_gain(X, y, feature) iv entropy(X[feature]) # 特征固有值 return gain / iv if iv ! 0 else 0多分类问题信息熵计算可自然扩展到多分类但特征重要性解释会更复杂# 多分类熵计算示例 def entropy_multi(labels): _, counts np.unique(labels, return_countsTrue) probabilities counts / len(labels) return -np.sum(probabilities * np.log2(probabilities 1e-10)) # 避免log(0)与互信息的关系信息增益实际上就是特征与标签的互信息可用sklearn.feature_selection.mutual_info_classif直接计算from sklearn.feature_selection import mutual_info_classif mi mutual_info_classif(X_processed, y, discrete_features[0,1]) print(互信息结果:, mi)在真实业务场景中我通常会先计算各特征的信息增益做初步筛选再结合业务知识和模型表现做最终决策。比如在金融风控中虽然某些字段的信息增益高但可能因为监管要求或可解释性考虑而选择其他特征。

相关新闻