Как выбрать конвейер sklearn для классификатора с несколькими метками / один против остальных? - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь создать классификатор с несколькими метками, используя оболочку классификатора 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]) после загрузки конвейера я получаю только один массив значений в предикторе.Если я подгоняю конвейер, я получаю массив из трех значений.

Кроме того, как я могу включить поиск по сетке в свой конвейер для экспорта?

raw_data

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)))

1 Ответ

0 голосов
/ 10 марта 2019

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"])

. Вы можете преобразовать ваши мультиклассовые метки в бинарную форму, используя MultiLabelBinarizer, прежде чем передавать их в метод fit

Пример:

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"])
...