调用已训练的文本多分类逻辑回归模型predict方法时报特征维度不匹配错误
报错原因定位
这个ValueError的核心是输入到模型的特征维度和模型训练时适配的维度完全不匹配,结合你的代码和报错数值,问题来源非常明确:
- 你的模型训练阶段,两个文本字段(
short_description、details)分别经过TF-IDF向量化,每个字段配置的max_features=50000,两个字段的向量化结果拼接后刚好是10万维特征,这就是报错中“expecting 100000”的来源。 - 你做测试预测时,没有调用训练阶段已经拟合完成的向量化组件处理文本,反而临时新建了一套TF-IDF转换器处理单条测试文本。单条文本本身的词汇量极少,新的转换器没有训练阶段沉淀的10万条词汇表,只能统计当前样本自身的词汇得到30个特征,维度差了几个量级,自然触发维度不匹配的报错。
另外你的现有预处理代码还埋了一个隐蔽的bug:两个文本分支直接复用同一个tfidf_pipeline实例的写法不符合scikit-learn的组件使用规则。ColumnTransformer在拟合时,同一个有状态的transformer实例绑定多个列,内部学习到的词表状态会被后处理的列覆盖,根本达不到两个字段独立向量化再拼接的效果,哪怕你后续流程都正确,攒出来的特征维度也达不到10万。
具体解决方案
- 第一步:修正预处理管道的组件定义,给两个文本字段创建独立的TF-IDF管道实例,避免状态互相覆盖,修正后的核心代码参考:
# 两个文本列分别初始化独立的TF-IDF管道 short_desc_tfidf = Pipeline([ ('tfidf' ,TfidfVectorizer(max_features=50000, ngram_range=(1, 3), stop_words = 'english', strip_accents= 'ascii')) ]) details_tfidf = Pipeline([ ('tfidf' ,TfidfVectorizer(max_features=50000, ngram_range=(1, 3), stop_words = 'english', strip_accents= 'ascii')) ]) preprocessor_pipeline = ColumnTransformer( transformers=[ ('short_description', short_desc_tfidf, 'short_description'), ('details', details_tfidf, 'details') ]) - 第二步:把“预处理管道 + 逻辑回归分类器”整合成端到端的scikit-learn管道,不要单独把逻辑回归模型拆出来存储。比如完整的训练管道可以写成:
from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline full_prediction_pipeline = Pipeline([ ('preprocess', preprocessor_pipeline), ('classifier', LogisticRegression()) ]) # 用全量训练数据拟合这个完整管道 full_prediction_pipeline.fit(X_train, y_train) - 第三步:预测阶段不要手动做文本向量化,直接把和训练时格式完全一致的原始测试数据(包含
short_description、details字段的DataFrame/字典格式)喂给之前拟合好的full_prediction_pipeline,由管道内部自动调用训练时沉淀的10万维词表完成向量化,再输出预测结果。 - 避坑提醒:如果测试的是单条样例,构造测试数据时要严格对齐训练时的列名和数据结构,不要随意改列名、拆文本字段,否则会因为ColumnTransformer找不到对应输入列,再次触发维度错误。
内容的提问来源于stack exchange,提问作者Snorrlaxxx
相关产品推荐
相关产品推荐

