为了创建机器学习算法,我创建了一个字典列表,并使用 scikit 的 DictVectorizer 为每个项目创建一个特征向量。然后,我使用部分数据进行训练,从数据集中创建了一个 SVM 模型,然后在测试集上测试该模型(您知道,这是典型的方法)。一切都很顺利,现在我想将模型部署到野外,看看它如何处理新的、未标记的、看不见的数据。如何保存特征向量,以便新数据具有相同的大小/特征并适用于 SVM 模型?例如,如果我想训练单词的存在:
[{
'contains(the)': 'True',
'contains(cat)': 'True',
'contains(is)': 'True',
'contains(hungry)': 'True'
}...
]
我用一个列表进行训练,该列表具有相同的句子和数千种动物变体。当我对列表进行矢量化时,它会考虑提到的所有不同动物,并在向量中为每个动物创建一个索引(“the”、“is”和“hungry”不会改变)。现在,当我尝试在新句子上使用该模型时,我想预测一个项目:
[{
'contains(the)': 'True',
'contains(emu)': 'True',
'contains(is)': 'True',
'contains(hungry)': 'True'
}]
如果没有原始训练集,当我使用 DictVectorizer 时它会生成:(1,1,1,1)。这比用于训练模型的原始向量少了几千个索引,因此 SVM 模型无法使用它。或者,即使向量的长度是正确的,因为它是在大量句子上训练的,但特征可能与原始值不对应。如何获得新数据以符合训练向量的维度?特征永远不会多于训练集,但不能保证所有特征都出现在新数据中。
有没有办法使用pickle来保存特征向量?或者我考虑过的一种方法是生成一个字典,其中包含值为“False”的所有可能特征。这会强制新数据采用适当的向量大小,并且仅计算新数据中存在的项目。
我觉得我可能没有充分描述问题,所以如果有不清楚的地方我会尝试更好地解释。先感谢您!
编辑:感谢拉斯曼的回答,解决方案非常简单:
from sklearn.pipeline import Pipeline
from sklearn import svm
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False)
svm_clf = svm.SVC(kernel='linear')
vec_clf = Pipeline([('vectorizer', vec), ('svm', svm_clf)])
vec_clf.fit(X_Train,Y_Train)
joblib.dump(vec_clf, 'vectorizer_and_SVM.pkl')
管道和支持向量机根据数据进行训练。现在,所有未来的模型都可以取消管道并在 SVM 中内置特征向量化器。