Логистическая регрессия, TensorFlow Keras или XGBoost

Вышеупомянутые вопросы прямо отражают существенную важность возможностей обнаружения мошенничества в банковском и финансовом секторе. Тем не менее, очень жаль, что финансовые учреждения не хотят переключаться на более продвинутые технологии, такие как машинное обучение и механизмы глубокого обучения, из-за ограничений, установленных регулирующими органами, а банки придерживаются оригинальных (и, честно говоря, хорошо зарекомендовавших себя) системы, основанные на правилах.

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

Здесь я собираюсь сравнить эффективность нескольких инструментов, которые также математически различаются, при обнаружении мошеннических транзакций. Для этого я использовал набор данных, предоставленный Machine Learning Group - ULB как часть Данные по обнаружению мошенничества с кредитными картами на Kaggle.

Наборы данных содержат транзакции, совершенные с помощью кредитных карт в сентябре 2013 года европейскими держателями карт, которые представляют транзакции, которые произошли за два дня, из которых у нас 492 мошенничества из 284 807 транзакций.

Набор данных сильно несбалансирован, на положительный класс (мошенничество) приходится 0,172% всех транзакций. Этот вопрос является корнем чрезвычайной сложности в этой теме - чрезвычайно несбалансированных данных, которые я объяснил, как преодолеть дальше.

Примечания к текущей статье:

  • Впервые я использовал Google Colab для написания кода Python. Однако я не могу выделить ничего удивительного в этом опыте, в отличие от Jupyter Notebook. Причина, по которой я использовал Colab, заключалась в основном в TensorFlow.
  • Алгоритмы Logistic Regresion, tf.Keras и Xgboost используются для прогнозирования мошеннической транзакции, а результаты сравниваются с точки зрения точности и отзыва .

Полный код Python доступен на моем Github.

Давайте прыгнем в это 😏

1. Импортируйте данные с Google Диска.

Загрузите файл csv с моего Google Диска и сохраните его во фрейме данных Pandas.

# Code to read csv file into Colaboratory:
!pip install -U -q PyDrive
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
------
# Authenticate and create the PyDrive client.
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)

В процессе импорта файла csv с Google Диска необходимо ввести файл ID. Посмотрите на третий метод, представленный здесь, если вы хотите узнать подробности.

#you need to enter your file id
id = '1grwIZR_LdcdyirULSoJ_VFhtuPpv00AB'
----
downloaded = drive.CreateFile({'id':id})
downloaded.GetContentFile('Filename.csv')
----
data = pd.read_csv('Filename.csv')
# Dataset is now stored in a Pandas Dataframe

Наши данные содержат 284 807 записей в 31 столбце, из которых 30 столбцов содержат независимые переменные, которые теоретически объясняют изменения в нашей зависимой переменной. В нашем сценарии зависимая переменная - это двоичный столбец, показывающий, была ли транзакция мошеннической или подлинной.

Судя по описанию данных (изображение ниже), в нашем наборе данных есть различные диапазоны. В результате требуется нормализация данных, чтобы изменить значения числовых столбцов в наборе данных на общий масштаб.

2. Масштабирование фрейма данных

Я отделил зависимую переменную от независимых переменных. Помните, что нормализация выполняется только для независимых переменных.

X_data = data.iloc[:,0:30]
y_data = data.iloc[:,-1]

… А затем с помощью Standard Scaler нормализовал обучающий набор данных.

standard_scaler = preprocessing.StandardScaler()
X_standard_scaled_df = standard_scaler.fit_transform(X_data)

3. Извлечение признаков

Очевидно, что в алгоритмах машинного обучения вы имеете дело с компромиссом между дисперсией и смещением, и всегда сложно преодолеть проблему переобучения. Я использовал несколько методов и обнаружил, что Анализ главных компонентов дал лучший результат с точки зрения решения проблемы компромисса.

Компания Towards Data Science представила краткое и эффективное объяснение PCA. Если вы только что собираетесь стать специалистом по обработке данных, я предлагаю вам посмотреть… хороший материал!

# Make an instance of the Model
pca = PCA(10)

# fit and transform data frame in one jump
pca_selected = pca.fit_transform(X_standard_scaled_df)

Результат PCA интересен! Из функции извлечены 10 функций. Я конвертирую результат в кадр данных Pandas и смотрю на первые 5 строк.

4. Разделение данных обучения и тестирования

Как упоминалось ранее, самый сложный момент в отношении наборов данных о мошенничестве - это крайне несбалансированное распределение положительных и отрицательных случаев. Например, давайте взглянем на наш текущий набор данных, используя функцию .value_counts(), а затем проиллюстрируем его.

Результаты показывают, что имеется только 492 случая мошеннических транзакций из 284 807 записей, что составляет всего 0,1727% от всех выборок.

Вот и происходит разбиение чрезвычайно несбалансированного набора данных…

Поскольку мне нужно убедиться, что небольшое количество положительных классов распределяется пропорционально как в обучающих, так и в тестовых данных, я предпринимаю следующие шаги:

  1. отделить все положительные записи от отрицательных
data_class_0 = ready_data[ready_data['Class']==0]
data_class_1 = ready_data[ready_data['Class']==1]

2. Разлил каждый класс в поезд и тестовый набор,% 67 до% 33 соответственно

# Since the number of fraud transactions are too little in compare to non-fraud,
# I make sure that they are distributed proportionally in both train and test set
X_0 = data_class_0.iloc[:,0:-1]  #independent columns
y_0 = data_class_0.iloc[:,-1]    #target column i.e Class
X_1 = data_class_1.iloc[:,0:-1]  #independent columns
y_1 = data_class_1.iloc[:,-1]    #target column i.e Class
X_train_0, X_test_0, y_train_0, y_test_0 = train_test_split(X_0, y_0, test_size=0.33, random_state=42)
X_train_1, X_test_1, y_train_1, y_test_1 = train_test_split(X_1, y_1, test_size=0.33, random_state=42)

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

X_train = pd.concat([X_train_0, X_train_1])
y_train = pd.concat([y_train_0, y_train_1])
X_test = pd.concat([X_test_0 , X_test_1])
y_test = pd.concat([y_test_0 , y_test_1])

На этом этапе, если мы посмотрим на набор данных, у нас будет следующее:

Учитывая несбалансированный набор данных, следующим шагом будет сбалансировать наш независимый обучающий набор X_train.

5. Набор данных для тренировки баланса.

Прежде чем перейти к тому, что я сделал, вы можете ознакомиться с концепцией передискретизации и недостаточной выборки в целом. Вот хорошее объяснение от Machine Learning Mastery.

Я использовал функцию SMOTE() для балансировки текущей модели. В двух словах, SMOTE соответствует желаемому соотношению количества выборок в классе меньшинства к количеству выборок в классе большинства после повторной выборки. Проверьте здесь для полной документации. Для этого мы просто вводим:

sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X_train, y_train)

Теперь, если мы сравним набор данных до и после SMOTE, мы увидим волшебство.

Output:
Original dataset shape Counter({0: 190491, 1: 329})
Resampled dataset shape Counter({0: 190491, 1: 190491})

На этом этапе у нас есть (… наконец 😫) набор данных, готовый для моделирования.

6. Модель обнаружения мошенничества

Для этого я использовал 3 алгоритма и сравнил их результаты:

6.1. Логистическая регрессия

Как обсуждалось выше, логистическая регрессия является наиболее широко распространенным и используемым алгоритмом среди других в реальной банковской индустрии.

logisticRegr = LogisticRegression()
logit_model = logisticRegr.fit(X_train, y_train)
logit_predict = logisticRegr.predict(X_test)

Вот результат точности логистической регрессии:

In:
print(classification_report(y_test, logit_predict))
Out:

6.2. Нейронная сеть с глубоким обучением - TensorFLow.Keras

Второй алгоритм - это искусственная нейронная сеть, для которой я использовал TensorFLow Keras.

Входные и скрытые слои

  • Взглянув на код на моем Github, вы увидите, что я дважды пытался построить нейронную сеть. Один раз я установил единицы измерения = 10 для скрытых слоев, а второй раз - 32 (что является более распространенной практикой). Сеть с 32 единицами скрытого слоя дала более высокую точность.
  • Я также поиграл с количеством эпох, которое является еще одним важным гиперпараметром для решения проблемы переобучения. Я обнаружил, что 10 эпох заканчиваются переоборудованной моделью, и 5 из них были разумно приемлемыми.
  • Другой гиперпараметр - функция активации. На самом базовом уровне функция активации решает, должен ли активироваться нейрон или нет. Он принимает взвешенную сумму входов и смещения в качестве входных данных для любой функции активации. Шаговая функция, сигмовидная, ReLU, Tanh и Softmax - это примеры функций активации. Компания MissingLink представила хорошее резюме своей истории в статье 7 типов функций активации нейронных сетей.

Выходной слой

На выходе будет один двоичный слой, для которого я установил функцию активации сигмоида (👆).

# Initialising the ANN
classifier = keras.Sequential()

# Adding the input layer and the first hidden layer
classifier.add(keras.layers.Dense(units =32 , kernel_initializer = 'uniform', activation = 'relu', input_dim =10))
# Adding the output layer
classifier.add(keras.layers.Dense(units = 1, kernel_initializer = 'uniform', activation = 'sigmoid'))
# Compiling the ANN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# And finally
# Fitting the ANN to the Training set
model = classifier.fit(X_train.values, y_train.values, batch_size = 128, epochs = 5)

# Predicting the Test set results
y_pred = classifier.predict(X_test)
y_pred = (y_pred > 0.5)
Output:
93987/93987 [==============================] - 3s 31us/sample - loss: 0.0041 - accuracy: 0.9992

Посмотрим, как работает наша модель

print(classification_report(y_test, y_pred))

Пара массовок:

  • Матрица неточностей

  • Диаграмма ROC AUC

6.3. XGBoost

XGBoost означает e X treme G radient B oosting и представляет собой следующий уровень возможностей реализаций scikit-learn и R с новыми дополнениями. как регуляризация. Опять же, посмотрите MachineLearningMaster для дальнейших объяснений.

XGBoost есть,

алгоритм, который в последнее время доминирует в прикладном машинном обучении и соревнованиях Kaggle для структурированных или табличных данных.

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

Есть два важных гиперпараметра, на которые нужно обращать внимание: learning_rate и n-estimators. Они помогают решить проблему переобучения и повысить точность. Скорость моего обучения составила% 1, и я лучше «запоминаю», чем 10%. И, честно говоря, я считаю, что 10 000 n_estimators было лишним, но я все равно сделал это 😅.

# Learning rate = 0.01
XGB_classifier = XGBClassifier(n_estimators=10000, learning_rate=.01, maximize=True)
XGB_classifier.fit(X_train,y_train, eval_metric = 'aucpr')

Выход:

Далее используется модель для прогнозирования зависимых переменных на основе данных независимых тестов ...

XGB_classifier_predict_smote = XGB_classifier.predict(X_test)

… И сравните прогноз с фактическим зависимым набором тестов.

classification_report(y_test,XGB_classifier_predict_smote)

Наконец идет результат 👇

Сравнение результатов и заключение

«Каков наилучший показатель точности в нашем сценарии?»

хммм… 🤔 есть идеи ?!

Почему я вообще задал этот вопрос? Потому что помните ... банковское дело - это чувствительная отрасль, и каждый год она несет огромные убытки.

Чтобы ответить на этот вопрос, я хотел бы отослать вас к нашим друзьям, которые создают Confusion_Matrix… четыре (не) известных TP, FP, TN и FN.

Если вы подумаете о том, какой из четырех наиболее важен для нас, вы поймете, каков наилучший показатель точности. По сути, мы имеем дело с мошенническими транзакциями, поэтому критически важно не отмечать мошеннические транзакции как подлинные. Противоположное (обозначение отсутствия мошенничества как мошенничества) также требует больших затрат, но не столь критично.

Следовательно, приоритетом будет минимизация количества ложных отрицательных результатов. Это означает, что минимизирует количество «мошеннических транзакций, помеченных как подлинные». Соответственно, мы знаем, что нам нужно как можно больше улучшить показатель Отзывов.

Это Руководство идиота по матрице точности, припоминания и заблуждения мне очень помогло. Вы также можете взглянуть, если чувствуете, что не понимаете того, что я здесь говорю.

Сравнивая результаты трех алгоритмов, мы видим, что Точность кардинально не изменилась, хотя было существенное улучшение. в Вспомните от логистической регрессии до tf.Keras и от tf.Keras до XGBoost.

… И приз достается Xgboost за его скромный, математически мощный движок с градиентным усилением.