实体抽取SVM/感知机模型部署 特征维度不匹配报错解决
问题解答
推理阶段特征数要求
必须完全一致。SVM、Perceptron这类传统机器学习模型训练完成后,内部权重矩阵的维度是固定死的——训练时每一个输入特征对应权重矩阵里的一个专属权重,推理时如果特征数量对不上,核心的矩阵乘法运算根本跑不起来,必然报维度不匹配的错误。
报错根本原因
问题出在你的特征预处理流程逻辑错误:你处理训练集和处理新的推理数据时,分别独立拟合了特征生成工具(不管你是用词袋、TF-IDF还是自己写的规则提取token、POS标签特征,本质都是把离散符号转成固定长度数值向量的编码器)。
训练集上拟合编码器时,统计到的所有特征(词、POS组合、窗口特征等)总数是6155,所以训练输入是6155维;处理新数据时你重新在新文本上跑了编码器的拟合逻辑,新文本里出现了不少训练集里没见过的词、特征组合,最终生成的特征总数涨到了6747,和模型预期的输入维度对不上,自然报错。
可落地的修复方案
- 严格遵守预处理规则:所有特征编码器、归一化工具都只能在训练集上拟合一次,推理阶段只能用训练好的预处理器对新数据做
transform转换,绝对不能在新数据上重新执行fit或者fit_transform操作。 - 把特征提取和模型训练打包成Pipeline,从流程上杜绝维度错配、数据泄露问题,参考逻辑如下:
from sklearn.pipeline import Pipeline from sklearn.linear_model import Perceptron # 把你的自定义特征生成器和模型串成一个整体 model_pipe = Pipeline([ # 特征提取组件,只会在训练时fit一次 ("feature_extractor", your_custom_feature_builder), ("classifier", Perceptron(verbose=10, n_jobs=-1, max_iter=10)) ]) # 训练时直接喂原始的文本/标注数据,不用单独转特征 model_pipe.fit(X_train_raw, y_train) # 推理时直接喂新的原始文本,Pipeline自动完成特征转换,不会出现维度不匹配 predictions = model_pipe.predict(X_new_raw)
- 针对NER场景的未登录词问题,不要给训练集没出现过的词新增特征维度,提前在特征生成器里预留
<UNK>(未知词)专属特征位,所有训练阶段没见过的词统一映射到这个特征位,保证不管输入什么文本,输出的特征维度始终和训练时一致。 - 额外提一句:如果你是把序列标注拆成逐token独立样本喂给普通Perceptron/SVM,效果会打折扣——这类模型没法学习标签之间的转移依赖(比如软技能实体的B/I标签约束),同场景下换成CRF或者端到端序列标注模型效果会好很多。
内容的提问来源于stack exchange,提问作者Thijs Kalshoven
相关产品推荐
相关产品推荐

