python - 如何为多标签分类器/一对休息分类器腌制 sklearn 管道?
问题描述
我正在尝试使用 one vs rest 分类器包装器创建一个多标签分类器。
我为 TFIDF 和分类器使用了一个管道。
在拟合管道时,我必须按类别循环遍历我的数据,然后每次拟合管道以对每个类别进行预测。
现在,我想像通常使用 pickle 或 joblib 导出拟合模型一样导出它。
例子:
pickle.dump(clf,'clf.pickle')
我怎样才能用管道做到这一点?即使我腌制管道,每次我想预测一个新关键字时,我是否仍然需要拟合管道?
例子:
pickle.dump(pipeline,'pipeline.pickle')
pipeline = pickle.load('pipeline.pickle')
for category in categories:
pipeline.fit(X_train, y_train[category])
pipeline.predict(['kiwi'])
print (predict)
如果我在加载管道后跳过pipeline.fit(X_train, y_train[category])
,我只会在预测中得到一个值数组。如果我适合管道,我会得到一个三值数组。
另外,如何将网格搜索合并到我的导出管道中?
原始数据
keyword class1 class2 class3
"orange apple" 1 0 1
"lime lemon" 1 0 0
"banana" 0 1 0
categories = ['class1','class2','class3']
管道
SVC_pipeline = Pipeline([
('tfidf', TfidfVectorizer(stop_words=stop_words)),
('clf', OneVsRestClassifier(LinearSVC(), n_jobs=1)),
])
Gridsearch(不知道如何将其合并到管道中)
parameters = {'tfidf__ngram_range': [(1, 1), (1, 2)],
'tfidf__use_idf': (True, False),
'tfidf__max_df': [0.25, 0.5, 0.75, 1.0],
'tfidf__max_features': [10, 50, 100, 250, 500, 1000, None],
'tfidf__stop_words': ('english', None),
'tfidf__smooth_idf': (True, False),
'tfidf__norm': ('l1', 'l2', None),
}
grid = GridSearchCV(SVC_pipeline, parameters, cv=2, verbose=1)
grid.fit(X_train, y_train)
装配管道
for category in categories:
print('... Processing {}'.format(category))
SVC_pipeline.fit(X_train, y_train[category])
# compute the testing accuracy
prediction = SVC_pipeline.predict(X_test)
print('Test accuracy is {}'.format(accuracy_score(y_test[category], prediction)))
解决方案
OneVsRestClassifier 在内部适合每个类一个分类器。所以你不应该像你在做的那样为每个班级安装管道
for category in categories:
pipeline.fit(X_train, y_train[category])
pipeline.predict(['kiwi'])
print (predict)
你应该做这样的事情
SVC_pipeline = Pipeline([
('tfidf', TfidfVectorizer()), #add your stop_words
('clf', OneVsRestClassifier(LinearSVC(), n_jobs=1)),
])
SVC_pipeline.fit(["apple","boy","cat"],np.array([[0,1,1],[1,1,0],[1,1,1]]))
您现在可以使用保存模型
pickle.dump(SVC_pipeline,open('pipeline.pickle', 'wb'))
稍后您可以加载模型并使用
obj = pickle.load(open('pipeline.pickle', 'rb'))
obj.predict(["apple","boy","cat"])
您可以在将多类标签传递给 fit 方法之前使用 MultiLabelBinarizer 对多类标签进行二值化
样本:
from sklearn.preprocessing import MultiLabelBinarizer
y = [['c1','c2'],['c3'],['c1'],['c1','c3'],['c1','c2','c3']]
mb = MultiLabelBinarizer()
y_encoded = mb.fit_transform(y)
SVC_pipeline.fit(["apple","boy","cat", "dog", "rat"], y_encoded)
使用网格搜索(示例)
grid = GridSearchCV(SVC_pipeline, {'tfidf__use_idf': (True, False)}, cv=2, verbose=1)
grid.fit(["apple","boy","cat", "dog", "rat"], y_encoded)
# Save the pipeline
pickle.dump(grid,open('grid.pickle', 'wb'))
# Later load it back and make predictions
grid_obj = pickle.load(open('grid.pickle', 'rb'))
grid_obj.predict(["apple","boy","cat", "dog", "rat"])
推荐阅读
- python - 循环遍历车号列表以计算每辆车的转向角平均值
- python - 如何创建一个函数等待表达式为真,然后返回其中的一部分
- javascript - JS包发布者可以指向模块的相对目录吗?
- c# - 使用 API 调用在 CRM 中将自定义对象链接在一起
- php - 如何在 PHP 中使用 Graph API 更新 Exchange365 自动回复
- npm - 为什么即使安装了 6.9.2,NPM 仍然显示 6.4.1?
- html - 如何编辑网站的背景颜色
- html - 如何在圆形轮播周围环绕文字?
- java - 没有任何 TimeZone 信息的 Java 日期时间开始和结束
- php - 如何使 PHP Ticker Number 分配更加健壮?