Anaconda Jupyter中决策树model.features_names_in失效问题求解
解决方案
在Anaconda环境的Jupyter Notebook中,完全可以通过sklearn原生接口正确获取决策树模型的特征名称,无需额外适配工具包,绝大多数相关报错都来自版本不匹配、参数传递错误、特征矩阵格式错误三类问题。
第一步:先排查环境版本
sklearn 1.0及以上版本原生支持特征名自动存储,0.24以下的旧版本无该特性,先在Notebook单元格中运行以下代码检查版本:
import sklearn print(sklearn.__version__)
若版本低于1.0,直接在对应conda环境中执行升级命令即可:
conda install scikit-learn=1.3.0 -c conda-forge
第二步:正确训练模型以自动留存特征名
训练模型时,传入的特征矩阵X请直接使用带列名的pandas DataFrame,不要调用.values或.to_numpy()将其转为numpy数组——numpy数组不会存储列名信息,转后会直接丢失特征名。
训练完成后,可直接通过模型内置属性读取特征名:
from sklearn.tree import DecisionTreeClassifier # 初始化模型 clf = DecisionTreeClassifier(max_depth=3, random_state=42) # 传入带列名的DataFrame格式X_train完成训练 clf.fit(X_train, y_train) # 直接读取模型存储的特征名称 feature_names = clf.feature_names_in_
第三步:可视化/特征重要性计算时显式传参避免报错
不管是用plot_tree做内置可视化,还是用export_graphviz做导出可视化,不要依赖接口自动识别特征名,显式传入feature_names参数可100%规避特征名显示为X[0]、X[1]或传参报错问题:
from sklearn.tree import plot_tree import matplotlib.pyplot as plt plt.figure(figsize=(20, 12)) plot_tree( clf, feature_names=X_train.columns, # 显式传入特征名 class_names=["负样本", "正样本"], # 按实际分类标签填写 filled=True, rounded=True ) plt.show()
计算特征重要性时也可直接传入特征名匹配结果:
# 输出按重要性降序排列的特征-重要性值对 feature_importance = sorted( zip(X_train.columns, clf.feature_importances_), key=lambda x: -x[1] ) print(feature_importance)
旧版本兼容方案
若因环境限制无法升级sklearn,无需依赖模型内置属性,手动维护和特征矩阵顺序完全一致的特征名列表,在所有需要特征名的接口中显式传入该列表即可:
# 手动获取特征名列表,保证和X_train列顺序完全一致 feature_names = X_train.columns.tolist() # 后续可视化、特征重要性计算均传入该列表即可
注意:如果做了特征选择、train_test_split等操作,要保证特征名列表的顺序和传入模型的特征矩阵列顺序完全一致,否则会出现特征名和分裂规则不匹配的问题。
内容的提问来源于stack exchange,提问作者Harsh780
相关产品推荐
相关产品推荐

