使用预训练BoW、TF-IDF及SVM模型预测时出现特征数不匹配错误
解决特征数不匹配问题:ValueError: Input has n_features=10 while the model has been trained with n_features=4261
咱们先把问题根源说清楚:这个错误的核心是训练阶段和预测阶段用了两套完全不同的特征规则。你训练SVM时,CountVectorizer是基于训练数据集的所有词汇构建了4261个特征的空间,但预测新数据时,如果你又调用了bagOfWords函数,它会重新针对新数据的词汇表构建特征空间(这次只有10个特征),两者的特征维度完全不匹配,模型自然没法处理。
接下来直接上解决方案,分两步走:
1. 训练阶段:把特征提取器和模型一起保存
训练时不能只保存SVM模型,必须把CountVectorizer和TfidfTransformer也存下来——它们记录了训练数据的词汇表、TF-IDF统计规则,是保证特征空间一致的关键。修改你的训练代码:
import joblib import sklearn.feature_extraction.text import sklearn.svm # 加载训练数据 files = sklearn.datasets.load_files(dir_path) # 初始化并训练特征提取器(只在训练数据上调用fit!) count_vector = sklearn.feature_extraction.text.CountVectorizer() word_counts_train = count_vector.fit_transform(files.data) tf_transformer = sklearn.feature_extraction.text.TfidfTransformer(use_idf=True) X_train_tfidf = tf_transformer.fit_transform(word_counts_train) # 训练SVM模型 clf = sklearn.svm.LinearSVC() clf.fit(X_train_tfidf, files.target) # 保存三个核心对象:特征提取器+模型 joblib.dump(count_vector, 'count_vectorizer.pkl') joblib.dump(tf_transformer, 'tfidf_transformer.pkl') joblib.dump(clf, 'svm_model.pkl')
2. 预测阶段:复用已保存的特征提取器
预测新数据时,绝对不能再调用fit/fit_transform,只能用transform方法,这样会严格沿用训练时的特征空间:
import joblib # 加载之前保存的对象 count_vector = joblib.load('count_vectorizer.pkl') tf_transformer = joblib.load('tfidf_transformer.pkl') clf = joblib.load('svm_model.pkl') # 定义预测函数 def predict_new_texts(new_texts): # 用训练好的CountVectorizer转换新文本(用transform,不是fit_transform!) word_counts_new = count_vector.transform(new_texts) # 用训练好的TfidfTransformer转换词频 X_new_tfidf = tf_transformer.transform(word_counts_new) # 执行预测 return clf.predict(X_new_tfidf)
避坑提醒
- 别再用原来的
bagOfWords函数处理预测数据了,它每次都会重新fit新数据,直接导致特征空间不一致。 - 所有特征提取的规则(词汇表、IDF权重)都必须和训练阶段完全一致,这是机器学习预测的基本准则。
内容的提问来源于stack exchange,提问作者user8142520
相关产品推荐
相关产品推荐

