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

Posted

技术标签:

【中文标题】在 scikit-learn 中保存新数据的特征向量【英文标题】:Saving a feature vector for new data in scikit-learn 【发布时间】:2014-07-31 21:10:46 【问题描述】:

为了创建机器学习算法,我制作了一个字典列表,并使用 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”。这会强制新数据进入适当的向量大小,并且只计算新数据中存在的项目。

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


编辑:感谢 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】:

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

通过使用transform 方法而不是fit_transform。后者从您输入的数据集中学习新词汇。

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

腌制经过训练的矢量化器。更好的是,制作矢量化器和 SVM 的 Pipeline 并将其腌制。您可以使用sklearn.externals.joblib.dump 进行高效酸洗。

(顺便说一句:如果你传递布尔值True而不是字符串"True",向量化器会更快。)

【讨论】:

能否详细说明Pipeline 的含义?我可以单独转储每个对象,但是有办法一起做吗?另外,谢谢您的回复。 fit_transform 函数是我出错的地方。

以上是关于在 scikit-learn 中保存新数据的特征向量的主要内容,如果未能解决你的问题,请参考以下文章

python - 如何在python scikit-learn中进行字典向量化后预测单个新样本?

如何在 scikit-learn 中控制随机森林中的特征子集?

为 Scikit-Learn 向量化 Pandas 数据框

scikit-learn,将特征添加到矢量化文档集

在 scikit-learn 中从 PCA 中查找和利用特征值和特征向量

如何将功能管道从 scikit-learn V0.21 移植到 V0.24