Как повысить точность моделей?

Большинству наверняка знакомо чувство, которое возникает, когда до заветной цели не хватает всего чуть-чуть, но вы никак не можете преодолеть эту мелочь. Не самое приятное чувство, правда? В статье мы поделимся одним из способов, как можно повысить точность ваших ML моделей.

Всё чаще приходится работать с ML для предсказания заданных параметров, классификации, кластеризации и т.п. Довольно часто возникают ситуации, когда, достигнув определённой точности модели, мы больше не можем улучшить этот показатель, используя стандартные методы и «коробочные» решения. Упираемся в стенку.

Однако, достигнутая точность по тем или иным причинам может нас не устраивать. Например, при необходимости классификации нескольких сотен тысяч объектов 1%, представленный 1000 неверно классифицируемых образцов, может быть существенным. Всё зависит от ситуации.

В данной статье мы хотели бы поделиться одним из вариантов повышения предсказательной мощности моделей машинного обучения на примере задачи классификации.

Задача заключалась в классификации текстов по разным темам. Скорость работы была немаловажным фактором, поэтому изначально мы использовали быстрый линейный классификатор LinearSVC.

В качестве метрики мы использовали взвешенную F1-score, а по различным классам анализировали метрики precision и recall.

Стандартными изученными способами мы смогли добиться значения f1-score на уровне 0,81. Но необходимо было значение 0,85.

Мы сделали следующее. Разделили первоначальную обучающую выборку для исходной модели ещё на 2 части. По первой части мы обучили три модели. Например, так:

In [ ]: calibrated_cv = CalibratedClassifierCV( LinearSVC( C = 3, intercept_scaling = 1, class_weight = 'balanced', random_state = 412 ), method = 'sigmoid', cv = 5 ) text_clf_fl_first = Pipeline( [ ('tfidfV', TfidfVectorizer( lowercase=True, sublinear_tf=True, min_df=10, norm='l2', encoding='utf8', ngram_range=(1, 4), stop_words=stop_wordus) ), ('clf', calibrated_cv) ]) _ = text_clf_fl_first.fit( df_tempr_fl_aos1['Answer'], df_tempr_fl_aos1['NewClassification'] )

Использовались модели из модуля scikit-learn. Вторая модель строилась на основе SGDClassifier, третья – LogisticRegression. CalibratedClassifierCV использовался для возможности получения вероятности предсказания (по тем моделям, в которых эта функция отсутсвует), Pipeline соответственно помогал конвейерной обработке входных данных и их предсказанию. Предсказательная мощность каждой модели около 0,81 по f1.

После обучения моделей, мы с помощью каждой сделали классификацию второй части обучающей выборки и сохранили данные в единый датасет. Также мы с помощью этих моделей сделали первичное предсказание на тестовой выборке.

Теперь самое интересное. Все предсказанные результаты мы будем рассматривать в качестве признаков и подадим их на вход четвёртой модели.

Для этого мы добавим в датасеты предсказанные столбцы и с помощью функции get_dummies() сформируем категориальные признаки по сделанным предсказаниям.

In [ ]: df3['Pred1'] = y_pred1 df3['Pred2'] = y_pred2 df3['Pred3'] = y_pred3 df4['Pred1'] = y_pred4 df4['Pred2'] = y_pred5 df4['Pred3'] = y_pred6 df4 = pd.concat([df3, df4]) df4 = pd.get_dummies(df4, columns = ['Pred1', 'Pred2', 'Pred3'])

В качестве 4-ой модели также используем LinearSVC.

In [ ]: _ = final_model.fit(df4.loc[df4.index.isin(df_pred_fl_aos1.index)].drop(['id', 'NewClassification', 'id_num_bp2'], axis = 'columns'), df4.loc[df4.index.isin(df_pred_fl_aos1.index)]['id_num_bp2']) y_pred_final = final_model.predict(df4.loc[df4.index.isin(df_predict4_fl_aos.index)].drop(['id', 'NewClassification', 'id_num_bp2'], axis = 'columns')) y_prob = text_clf_fl_first.predict_proba(x_t2)

В результате работы конечной модели предсказательная мощность по метрике f1 повысилась до 0,861, то есть мы достигли желаемой цели.
Надеемся, что наш опыт будет полезен и вам, и вы сможете использовать его в своей работе.

88 показов
3.6K3.6K открытий
Начать дискуссию