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

时间:2014-06-10 23:07:10

标签: python machine-learning scikit-learn

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

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

我训练的列表中有相同的句子,有数千种动物变种。当我对列表进行矢量化时,它会考虑所有提到的不同动物,并在每个动物的矢量中创建一个索引(''''饥饿' 39;不要改变)。现在,当我尝试在新句子上使用模型时,我想预测一个项目:

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

如果没有原始训练集,当我使用DictVectorizer时它会生成:(1,1,1,1)。这是用于训练我的模型的原始向量之外的几千个索引,因此SVM模型将无法使用它。或者即使向量的长度是正确的,因为它是在大量句子上训练的,因此这些特征可能与原始值不对应。如何获得新数据以符合训练向量的维度?永远不会有比训练集更多的功能,但并不是所有功能都保证存在于新数据中。

有没有办法使用pickle来保存特征向量?或者我认为的一种方法是生成一个字典,其中包含所有可能具有值' False'的功能。这会强制新数据进入适当的矢量大小,并仅计算新数据中的项目。

我觉得我可能没有充分描述这个问题,所以如果事情不清楚,我会尝试更好地解释它。提前谢谢!


编辑:感谢larsman的回答,解决方案非常简单:

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 个答案:

答案 0 :(得分:7)

  

如何使新数据符合训练向量的维度?

使用transform方法代替fit_transform。后者从您提供的数据集中学习新词汇。

  

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

挑选训练有素的矢量图。更好的是,制作一个Pipeline的矢量化器和SVM并腌制它。您可以使用sklearn.externals.joblib.dump进行有效的酸洗。

(旁白:如果你传递布尔值True而不是字符串"True",矢量化器会更快。)