You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SkLearn DecisionTree拟合未纳入数值特征、特征数不匹配报错解决

问题根因

报错和数值特征未入模的问题来自两处代码逻辑错误:

  • 定义ColumnTransformer时仅配置了分类特征的OneHotEncoder转换规则,未对数值特征指定处理逻辑。该转换器默认行为是丢弃所有未显式绑定转换器的列,因此数值列num1完全没有进入后续训练流程,模型实际仅接收到分类特征独热编码后生成的8个特征。
  • 导出决策树可视化代码时,手动将原始数值列名与独热编码输出列名拼接得到9个特征名,与模型实际输入的8个特征数量不符,直接触发Length of feature_names, 9 does not match number of features, 8报错。
修复方案
  1. 给ColumnTransformer补充数值特征的处理分支:决策树基于特征分裂阈值训练,对数值特征尺度不敏感,数值列可直接用passthrough参数透传;如果数值列存在缺失值,可搭配SimpleImputer做缺失值填充后再传入模型。
  2. 不要手动拼接特征名:拟合完成后直接调用ColumnTransformer的get_feature_names_out()方法,即可拿到包含透传数值列、独热编码分类列在内的全部输出特征名称,完全避免特征名长度不匹配问题。

修正后的可运行代码如下:

import pandas as pd
import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import graphviz 

# 示例数据集
df = pd.DataFrame({'brand'      : ['aaaa', 'asdfasdf', 'sadfds', 'NaN'],
                   'category'   : ['asdf','asfa','asdfas','as'], 
                   'num1'       : [1, 1, 0, 0] ,
                   'target'     : [1,0,0,1]})

dtarget = df['target']
dfeatures = df.drop('target', axis=1)

# 区分数值、分类特征列
num_cols = dfeatures.select_dtypes(include=["int64"]).columns.tolist()
cat_cols = dfeatures.select_dtypes(include=["object"]).columns.tolist()

# 列转换器:同时处理分类、数值特征
transformer = ColumnTransformer(
    transformers=[
        ("cat", OneHotEncoder(handle_unknown='ignore'),  cat_cols),
        ("num", SimpleImputer(strategy="median"), num_cols) # 无缺失值可替换为"passthrough"直接透传
    ]
)

clf = DecisionTreeClassifier(criterion="entropy", max_depth=5)

# 组装训练管道
pipe = Pipeline(steps=[
                ('col_transformer', transformer),
                ('decisiontree', clf)
                ])

# 模型拟合
pipe.fit(dfeatures, dtarget)

# 获取转换后的全部特征名,无需手动拼接
correct_feature_names = pipe.named_steps['col_transformer'].get_feature_names_out().tolist()

# 导出决策树可视化结构
dot_data = tree.export_graphviz(
    clf,
    out_file=None,
    feature_names=correct_feature_names, 
    class_names=['0', '1'],
    filled=True
)

# 生成可视化文件
graph = graphviz.Source(dot_data)
graph.render("decision_tree_result")
补充说明
  • 树模型不需要对数值特征做StandardScaler标准化处理,该步骤不会提升模型效果,只会增加计算冗余。
  • OneHotEncoder添加handle_unknown='ignore'参数后,预测阶段遇到训练集未出现过的分类值时不会直接报错,会将该样本对应独热编码位全部置0。
  • 原代码中存在重复导入、导入未使用依赖的问题,修正代码中已经做了清理,不清理也不会影响核心逻辑运行。

内容的提问来源于stack exchange,提问作者esokumamon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:12:13