开发ExtraTreesClassifier模型Flask预测UI时遇到特征数不匹配报错
ExtraTreesClassifier Flask部署推理特征数不匹配问题排查
流程与异常梳理
- 训练阶段操作
- 读取清洗后的训练数据集,将
click_time字段转换为日期格式后,剔除is_attributed、click_time两列 - 选取剩余7个字段(ip、app、device、os、channel、hour、day)作为模型输入特征X,将
is_attributed列作为预测目标y - 经RandomUnderSampler随机欠采样平衡样本分布、拆分训练测试集后,使用ExtraTreesClassifier完成模型训练,本地调用
gsec.predict(X_test)可正常输出预测结果
- 读取清洗后的训练数据集,将
- 部署环节报错现象
- 将训练完成的模型通过pickle序列化保存后,在Flask推理接口中加载模型做预测时,触发报错:
ValueError: X has 500000 features, but ExtraTreeClassifier is expecting 7 features as input
- 将训练完成的模型通过pickle序列化保存后,在Flask推理接口中加载模型做预测时,触发报错:
- 认知偏差说明
- 所用测试集文件共50万条数据、7个列,曾误以为训练模型时是以
is_attributed单列作为输入完成的,因此对特征数量不匹配的报错存在疑惑
- 所用测试集文件共50万条数据、7个列,曾误以为训练模型时是以
报错根因定位
sklearn 所有内置模型的predict接口对输入结构有强制要求:输入必须为二维数组,形状为
(样本数量, 特征数量)
- 报错提示的“500000个特征”,与测试集的总样本数(50万条)完全对应,并非测试集列数不符合要求。核心问题是推理流程中读入测试数据后,未做维度校验就将转置后的数组传入predict接口
- 原本形状为(500000, 7)的测试数据,被转置为(7, 500000),此时数组的第二维(即模型识别到的特征维度)变为500000,与模型训练时记忆的“7个特征输入”要求完全不匹配,直接触发报错
- 训练流程的特征定义不存在问题:
is_attributed从流程初始就被设为预测目标而非输入特征,模型从训练阶段就明确要求7个特征的输入维度,根本不存在“用is_attributed单特征训练模型”的情况,这个认知误区可以直接排除
修复方案
- 在Flask推理接口接收到上传的测试数据后,先打印校验数据的
shape属性,确保传入model.predict()的数组形状为(n_samples, 7)——第一维对应样本数、第二维对应7个输入特征,维度顺序错了的话第一时间就能发现 - 排查推理代码中是否存在隐式的行列转置操作(比如pandas的
.T方法、numpy的.transpose()调用),这类没有加注释的转置操作,是触发该类特征数不匹配报错的最常见原因
内容的提问来源于stack exchange,提问作者CodeGirl
相关产品推荐
相关产品推荐

