提问者:小点点

在scikit learn中为新数据保存特征向量


为了创建一个机器学习算法,我制作了一个字典列表,并使用Scikit的DictVectorzer为每个项目制作了一个特征向量。然后,我从数据集中创建了一个SVM模型,使用部分数据进行训练,然后在测试集上测试模型(你知道,典型的方法)。一切都很好,现在我想把模型部署到野外,看看它是如何在新的、未标记的、看不见的数据上工作的。如何保存特征向量,以便新数据具有相同的大小/特征,并与SVM模型一起工作?例如,如果我想训练单词的存在:

[{
 'contains(the)': 'True',
 'contains(cat)': 'True',
 'contains(is)': 'True',
 'contains(hungry)': 'True'
 }...
]

我用一个列表来训练,这个列表中有成千上万种动物变体的同一句话。当我对列表进行向量化时,它会考虑所有提到的不同动物,并在向量中为每种动物创建一个索引(“the”、“is”和“hunger”不会改变)。现在,当我尝试在一个新句子上使用该模型时,我想预测一个项目:

[{
 '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中内置一个特征向量器。


共1个答案

匿名用户

如何获取新数据以符合训练向量的维度?

使用transform方法代替fit\u transform。后者从您提供给它的数据集中学习一个新词汇表。

有没有办法使用pickle保存特征向量?

对经过训练的矢量器进行Pickle。更好的方法是,将矢量器和SVM进行管道,并将其pickle。您可以使用sklearn。外部的。乔布里。倾倒,以实现高效酸洗。

(旁白:如果将布尔值True而不是字符串“True”传递给矢量器,则矢量器会更快)