Время прочтения: 4 мин.

Xgboost – популярная за счет своей производительности библиотека python, которая реализует методы градиентного бустинга деревьев решений.  А с помощью sklearn будем осуществлять препроцессинг и оценку качества модели. В качестве объектов у нас будут выступать сами потенциально мошеннические операции. Признаки – это наши критерии этих операций. Обучающими данными у нас выступят уже совершенные операции, признанные мошенническими.

Первый этап: собираем данные – в нашем случае они хранятся в БД:

import pandas as pd
stoks2 = pd.io.sql.read_sql(“Select …”, v_connect)
stoks2.head()

Нам необходимо разделить поля набора данных на входные признаки «X» и выходные метки «y». Добавляем поле в наш dataframe.

stoks2['TARGET']=0
stoks2.head()

На всякий случай проверим данные на NULL:

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax = plt.subplots(figsize=(6, 4))
(1-stoks2.isnull().mean()).abs().plot.bar(ax=ax)

Подготовка данных для «y»: поле со строковыми данными, которое нам в итоге надо превратить в метрику «y».

stoks2[' NEME FIELD '].value_counts(dropna=False) # Проверяем на пустые значения

Меняем строковые признаки на 0 и 1.

stoks2['TARGET'] = stoks2['NEME FIELD'].map(lambda x: 1 
                                             if(x=='SATATUS 1' 
                                                or x=='SATATUS 2'
                                                or x=='SATATUS 3 '
                                               ) else 0)

Формируем массивы «X» и «y», отбрасываем ненужные данные.

y=stoks2['TARGET']
X=stoks2.drop(["NEME FIELD 1", "NEME FIELD 2", "NEME FIELD 3", "NEME FIELD 4", "NEME FIELD 5", "NEME FIELD 5", "TARGET",], axis=1)
X.columns, X.head()

При помощи train_test_split из модуля model_selection библиотеки scikit-learn произвольным образом разделяем массивы «X» и «y» на тренировочные и тестовые наборы данных (в данном случае 30% от общего объема).

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_train.shape, X_test.shape, y_train.shape, y_test.shape

Возможно понадобится стандартизация наборов. Для этого используем модуль StandardScaler из Sklearn.

from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
sc.fit(X_train)
X_train=sc.transform(X_train)
X_test=sc.transform(X_test)

Построение и обучение модели xgboost.

Библиотека xgboost поддерживает регрессию. Она строит простое дерево, а затем «бустирует» его, добавляя последующие деревья.

Параметры:

max_depth – максимальная глубина дерева,

booster – может быть “gbtree”, “gblinear”, “dart”. Значение “dart” добавляет отбрасывание (отбрасывает случайные деревья, для предотвращения переобучения),

n_jobs   — количество потоков,

gamma – минимальное снижение потерь,

importance_type – тип важности признака,

base_score – первоначальный прогноз,

random_state – случайное начальное число,

n_estimators – количество раундов или расширяемых деревьев, eta – размер шага.

import xgboost
xgb_model = xgboost.XGBClassifier(booster='dart',
                                  max_depth=3,
                                  gamma=0)
xgb_model.fit(X_train, y_train, eval_metric=['auc', 'error'])

Отлично, модель построили. Теперь оценим качество предсказания:

y_pred = xgb_model.predict(X_test)
print('Число ошибок: %d' % (y_test != y_pred).sum())

Метод score в данном случае возвращает среднее значение точности прогнозирования.

xgb_model.score(X_test, y_test)

Также можно посмотреть другие метрики оценки благодаря модулю metrics из sklearn:

from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score
print(precision_score(y_test, xgb_model.predict(X_test)))
print(accuracy_score(y_pred, y_test))

Далее проверим корреляцию. Реализаций проверки много – я выбрал эту:

col_names = X_train.columns
for col, val in sorted(zip(col_names, gbm.feature_importances_), key=lambda x:x[1], reverse=True,)[:10]:
    print(f"{col:10}{val:10.3f}")

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

import xgboost as xgb
model = xgb.XGBClassifier()
gbm = model.fit(X_train, y_train)
gbm.score(X_test, y_test)

В первом случае используем GridSearchCV:

from sklearn.model_selection import cross_validate, GridSearchCV

params = {'n_estimators':[67, 70, 100, 120, 200, 315],
          'reg_lambda':[2, 1],
          'gamma':[0,0.3,0.2,0.1],
          'max_depth':list(range(3, 6)), 
          'learning_rate':[0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.05,0.09],
          'min_child_weight ':[1, 3, 5, 7, 9],    
}
clf=GridSearchCV(model, params, cv=10, n_jobs=-1, verbose=1)
clf.fit(X_train, y_train)

Во втором — RandomizedSearchCV:

from sklearn.model_selection import RandomizedSearchCV

params = {'n_estimators': [100, 200, 500, 800, 1000, 1200],
          'max_depth': [3,5,7],
          'objective': ['binary:logistic'],
          'min_child_weight': [1, 5, 10],
          'gamma': [0.5, 1, 1.5, 2, 5],
          }

rfc_cv = RandomizedSearchCV(model, params, cv = 10, n_jobs=-1, verbose=2).fit(X_train, y_train)

Итоговые параметры для Xgboost выглядят так:

model = xgb.XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
              colsample_bynode=1, colsample_bytree=1, gamma=0.2, gpu_id=-1,
              importance_type='gain', interaction_constraints='',
              learning_rate=0.05, max_delta_step=0, max_depth=3,
              min_child_weight = 1,
              monotone_constraints='()', n_estimators=305, n_jobs=0,
              num_parallel_tree=1, random_state=0, reg_alpha=0, reg_lambda=2,
              scale_pos_weight=1, subsample=1, tree_method='exact',
              validate_parameters=1, verbosity=None)
gbm = model.fit(X_train, y_train)
gbm.score(X_test, y_test)

Теперь мы можем сделать прогноз, применив обученную модель на тестовом и тренировочных наборах.

y_pred=gbm.predict(X_train)
t_pred=gbm.predict(X_test)
print(accuracy_score(y_pred, y_train))
print(accuracy_score(t_pred, y_test))
print(gbm.feature_importances_)

Формируем дополнительные поля для итоговой выгрузки:

xgb_predictions=xgb_model.predict(X)
xgb_probability=xgb_model.predict_proba(X)
xgb_probability=[max(row) for row in xgb_probability]

stoks2['ML П'] = pd.Series(xgb_predictions)
stoks2['ML В'] = pd.Series(xgb_probability)

Выгрузка результата в Excel:

stoks2.to_excel("xgboost.xlsx")

Вот и все на этом. Пробуя разные параметры для тюнинга xgboost, мы построили модель с приемлемым результатом (89%).