Время прочтения: 3 мин.
Digital audit всё в большей мере становится не модным новшеством в работе аудиторов, а скорее стандартом.
Всё чаще приходится работать с 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, то есть мы достигли желаемой цели.
Надеемся, что наш опыт будет полезен и вам, и вы сможете использовать его в своей работе.