Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Вступление

Выявление мошенничества является важнейшей задачей для различных отраслей, включая банковское дело, страхование и электронную коммерцию. Поскольку мошеннические действия становятся всё более изощрёнными, традиционных методов, основанных на правилах, может оказаться недостаточно для выявления мошеннических транзакций. Именно здесь методы машинного обучения, такие как логистическая регрессия, могут обеспечить более точное и эффективное решение. В этом всеобъемлющем руководстве мы углубимся в реализацию логистической регрессии для обнаружения мошенничества с использованием популярной библиотеки Sklearn на Python. Мы применим комплексный подход, используя набор данных с открытым исходным кодом от Kaggle, и продемонстрируем этапы построения модели логистической регрессии от предварительной обработки данных до оценки. К концу этого руководства вы будете иметь полное представление о том, как реализовать логистическую регрессию в Python для обнаружения мошенничества.

К концу этой статьи вы узнаете, как:

  • Разобраться в реализации логистической регрессии для обнаружения мошенничества с помощью Sklearn на Python.
  • Изучить необходимые этапы предварительной обработки, такие как очистка данных, нормализация и масштабирование объектов, перед построением модели.
  • Открыть для себя методы обработки несбалансированных наборов данных и поймёте, как оценивать производительность модели с использованием соответствующих показателей, таких как точность, прецизионность, отзыв и матрица путаницы.

Содержание

  • Что такое логистическая регрессия
  • Постановка задачи
  • Импорт данных и пакетов Python
  • Предварительный анализ данных
  • Логистическая регрессия и матрица путаницы
  • Переобучение и кривая обучаемости
  • Вывод

Что такое логистическая регрессия

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

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

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

Постановка задачи

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

Шаг 1: Импорт данных и пакетов Python

Давайте сначала импортируем все необходимые пакеты в Python:

# import the packages import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import sklearn.preprocessing as preprocessing from sklearn import linear_model from sklearn.cross_validation import cross_validation import sklearn.model_selection from sklearn import svm from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import GradientBoostingClassifier from sklearn.model_selection import learning_curve #from sklearn.grid_search import GridSearchCV from sklearn.metrics import explained_variance_score from sklearn.feature_extraction import DictVectorizer from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix from sklearn.metrics import accuracy_score from sklearn.metrics import classification_report from sklearn import metrics from sklearn.feature_selection import RFE %matplotlib inline import warnings warnings.filterwarnings("ignore")

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

#import the dataset and take a look at it df_all = pd.read_csv('creditcard.csv', header = 0) df_all.head(10) #df_all.columns
Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Шаг 2: Предварительный анализ данных

После загрузки набора данных важно получить глубокое представление о данных, прежде чем строить какую-либо модель. Этот процесс известен как предварительный анализ данных (EDA) и обычно он включает в себя следующие этапы:

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

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

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

#Understand the numberic variables #Continuous Variables featureConCols = ['V1', 'V2', 'V3', 'V4', 'V5', 'V6', 'V7', 'V8', 'V9', 'V10', 'V11', 'V12', 'V13', 'V14', 'V15', 'V16', 'V17', 'V18', 'V19', 'V20', 'V21', 'V22', 'V23', 'V24', 'V25', 'V26', 'V27', 'V28', 'Amount'] #Report the correlation table corr = df_all[featureConCols].corr() corr fig = plt.figure(figsize=(16, 12)) ax1 = fig.add_subplot(121) im1 = ax1.imshow(corr, interpolation='None') divider = make_axes_locatable(ax1) cax = divider.append_axes('right', size='5%', pad=0.05) fig.colorbar(im1, cax=cax, orientation='vertical')
#Report the distribution with target feature_names = featureConCols for i in range(len(feature_names)-1): figure = plt.figure() ax = sns.boxplot(x='Class', y=feature_names[i], data=df_all, showfliers = False)
Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Основываясь на приведённой выше информации, мы можем заметить, что класс (1) и класс (0) имеют существенно различающееся распределение среди функций V1, V2, V3 и V4. Этот вывод является для нас хорошим показателем для рассмотрения в процессе построения модели, поскольку он предполагает, что эти особенности могут оказывать значительное влияние на прогнозирование переменной результата, в которой, в данном случае, является наличие мошенничества. Принимая эту информацию во внимание, мы можем принять более обоснованные решения о том, какие функции включить в нашу модель и как предварительно обработать данные перед обучением модели.

Проведя предварительный анализ независимых переменных, мы также можем визуализировать целевой класс, чтобы получить представление о его распределении. Гистограмма показывает, что набор данных преимущественно состоит из не мошеннических транзакций, что указывает на проблему несбалансированного класса. Приведённый ниже фрагмент кода отображает ожидаемую точность модели с базовой точностью 0,9982. Однако классовый дисбаланс может снизить эффективность наших моделей. Напротив, если мы классифицируем все записи как класс (0), мы всё равно можем достичь точности в 99,82%.

#Understand the target variable target_count =df_all['Class'].value_counts() print("Class 0: ", target_count[0]) print("Class 1: ", target_count[1]) print("Proportion: ", round(target_count[0]/target_count[1], 2) ,': 1') df_all['Class'].value_counts().plot(kind = 'bar', title = 'Count(target)')
Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

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

Одним из способов улучшить запоминание является использование методов случайной выборки, таких как избыточная и недостаточная дискретизация. Избыточная выборка включает дублирование выборок из класса меньшинства, в то время как недостаточная выборка включает удаление выборок из класса большинства. Однако оба подхода имеют свои недостатки: избыточная дискретизация потенциально приводит к переобучению, а недостаточная - к потере важной информации.

Шаг 3: Логистическая регрессия и матрица путаницы

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

# Split the database into training and testing set df = df_all.drop(['Time'], axis = 1) df_target = df['Class'] X_train, X_test, y_train, y_test = train_test_split(df, df_target, test_size=0.2) # Data preprocessing to transfer all variables into array scaler = preprocessing.StandardScaler() vec = DictVectorizer(sparse = False) def Data_preprocessing(X,y): #1. Numerical vars into vector X_dataFeatureCon = X[featureConCols] X_dictCon = X_dataFeatureCon.T.to_dict().values() #2. Keep a dataframe of concat database before scaling X_all = X_dataFeatureCon #3. Vectorizing and scaling the nummerical variabled into range [-1,1] X_vec_con = vec.fit_transform(X_dictCon) X_vec_con = scaler.fit_transform(X_vec_con) X_vec = X_vec_con #5. Conver target into array y_vec = y.to_numpy() return X_vec, y_vec, X_all # Apply the Data_preprocessing function on training set and testing set X_train_vec, y_train_vec, X_train_frame = Data_preprocessing(X_train, y_train) X_test_vec, y_test_vec, X_test_frame = Data_preprocessing(X_test, y_test) print('X Train shape is : ', X_train_vec.shape) print('X Train DataFrame shape is: ', X_train_frame.shape) print('Y Train shape is : ', y_train_vec.shape) print('X Test shape is: ', X_test_vec.shape) print('X Test DataFrame shape is: ', X_test_frame.shape) print('Y Test shape is: ', y_test_vec.shape)
Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

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

# Under sampling and Over sampling #1. Create counts count_class_0, count_class_1 = df_target.value_counts() print(count_class_0) print(count_class_1) df_class_0 = df_all[df_all['Class']==0] df_class_1 = df_all[df_all['Class']==1] #2. Under sampling df_class_0_under = df_class_0.sample(count_class_1) df_test_under = pd.concat([df_class_0_under, df_class_1], axis=0) print('Random under-sampling:') print(df_test_under['Class'].value_counts()) df_test_under['Class'].value_counts().plot(kind='bar', title='Count (target)') #3. Over sampling df_class_1_over = df_class_1.sample(count_class_0, replace=True) df_test_over = pd.concat([df_class_0, df_class_1_over], axis=0) print('Random over-sampling:') print(df_test_over['Class'].value_counts()) df_test_over['Class'].value_counts().plot(kind='bar', title='Count (target)')
Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

LogisticRegression() и примем параметры по умолчанию. Однако важно знать некоторые из важнейших параметров:

  • penalty: По умолчанию = L2 — задает норму для штрафа
  • C: Default = 1.0 — Обратная сила регуляризации
  • solver: Default = ‘lbfgs’ — Алгоритм оптимизации.

Вот реализация кода для обучения и тестирования моделей логистической регрессии.

Модель 1 — без какой-либо выборки с параметрами по умолчанию в логистической регрессии:

# Model 1: Simple logistic regression with l2 regularization #1. Model parameters model1 = linear_model.LogisticRegression(C=1.0, penalty='l2', tol=1e-6) model1.fit(X_train_vec, y_train_vec) #2. Accuracy score on testing set y_pred = model1.predict(X_test_vec) accuracy = accuracy_score(y_test_vec, y_pred) print("Accuracy: %.2f%%" % (accuracy * 100.0)) #3. Confusion matrix conf_mat = confusion_matrix(y_true=y_test_vec, y_pred=y_pred) print('Confusion matrix:\n', conf_mat) labels = ['Class 0', 'Class 1'] fig = plt.figure() ax = fig.add_subplot(111) cax = ax.matshow(conf_mat, cmap=plt.cm.Blues) fig.colorbar(cax) ax.set_xticklabels([''] + labels) ax.set_yticklabels([''] + labels) plt.xlabel('Predicted') plt.ylabel('Expected') plt.show() #4. Classification report report = classification_report(y_test_vec, y_pred) print(report)

Ниже мы сообщили об общей точности, матрице путаницы и отзыве:

Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Мы видим, что общая точность составляет 99,91%, что кажется превосходным. Когда мы рассмотрели отзыв для класса (1), он составил всего 62%, что означает, что мы можем выявить только 62% фактического мошенничества.

Модель 2 — Моделирование с недостаточной дискретизацией с тем же параметром по умолчанию:

# Model 2: Simple logistic regression with l2 regularization on under sampling data #1. Get under sampling training set and testing set df_u = df_test_under.drop(['Time'], axis = 1) df_u_target = df_u['Class'] X_train_under, X_test_under, y_train_under, y_test_under = train_test_split(df_u, df_u_target, test_size=0.2) print(X_train_under.shape) print(X_test_under.shape) print(y_train_under.shape) print(y_test_under.shape) X_train_under_vec, y_train_under_vec, X_train_under_frame = Data_preprocessing(X_train_under, y_train_under) X_test_under_vec, y_test_under_vec , X_test_under_frame = Data_preprocessing(X_test_under, y_test_under) print('X Train shape is : ', X_train_under_vec.shape) print('Y Train shape is : ', y_train_under_vec.shape) print('X Test shape is: ', X_test_under_vec.shape) print('Y Test shape is: ', y_test_under_vec.shape) #2. Model parameters model2 = linear_model.LogisticRegression(C=1.0, penalty='l2', tol=1e-6) model2.fit(X_train_under_vec, y_train_under_vec) #2. Accuracy score on testing set y_pred = model2.predict(X_test_under_vec) accuracy = accuracy_score(y_test_under_vec, y_pred) print("Accuracy: %.2f%%" % (accuracy * 100.0)) #3. Confusion matrix conf_mat = confusion_matrix(y_true=y_test_under_vec, y_pred=y_pred) print('Confusion matrix:\n', conf_mat) labels = ['Class 0', 'Class 1'] fig = plt.figure() ax = fig.add_subplot(111) cax = ax.matshow(conf_mat, cmap=plt.cm.Blues) fig.colorbar(cax) ax.set_xticklabels([''] + labels) ax.set_yticklabels([''] + labels) plt.xlabel('Predicted') plt.ylabel('Expected') plt.show() #4. Classification report report = classification_report(y_test_under_vec, y_pred) print(report)

Ниже мы сообщили об общей точности, матрице путаницы и отзыве:

Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Хотя мы увидели, что общая точность снизилась до 90,86%, мы заметили, что отзыв для класса (1) был значительно увеличен до 94%; в этом случае мы можем выявить 94% общего мошенничества.

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

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

Шаг 4: Переобучение и кривая обучаемости

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

#3. Report the learning curve def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=1, train_sizes=np.linspace(.05, 1., 20), verbose=0, plot=True): """ Plot learning curve of applied data model. ---------- estimator : Classification title : title of plot X : features in numpy y : tearget in matrix ylim : tuple with (ymin, ymax) cv : cross-validation fold default as 3 n_jobs : """ train_sizes, train_scores, test_scores = learning_curve( estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes, verbose=verbose) train_scores_mean = np.mean(train_scores, axis=1) train_scores_std = np.std(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) test_scores_std = np.std(test_scores, axis=1) if plot: plt.figure() plt.title(title) if ylim is not None: plt.ylim(*ylim) plt.xlabel(u"Training examples") plt.ylabel(u"Score") plt.gca().invert_yaxis() plt.grid() plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, alpha=0.1, color="b") plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, alpha=0.1, color="r") plt.plot(train_sizes, train_scores_mean, 'o-', color="b", label=u"Training score") plt.plot(train_sizes, test_scores_mean, 'o-', color="r", label=u"Cross-validation score") plt.legend(loc="best") plt.draw() plt.gca().invert_yaxis() plt.show() midpoint = ((train_scores_mean[-1] + train_scores_std[-1]) + (test_scores_mean[-1] - test_scores_std[-1])) / 2 diff = (train_scores_mean[-1] + train_scores_std[-1]) - (test_scores_mean[-1] - test_scores_std[-1]) return midpoint, diff

Кривая обучения для модели логистической регрессии с недостаточной выборкой по умолчанию:

Пошаговое руководство по обнаружению мошенничества с использованием логистической регрессии Python: комплексный подход

Основываясь на графике кривой обучения, кажется, что оценка обучения и оценка перекрёстной проверки сходятся, что указывает на то, что наша модель не слишком соответствует данным обучения. Таким образом, мы можем сделать вывод, что подход с недостаточной выборкой эффективно решил проблему несбалансированности набора данных. Чтобы ещё больше повысить производительность нашей модели, мы могли бы изучить настройку гиперпараметров, скорректировав значение C или попробовав различные solvers, доступные в LogisticRegression().

Заключение

Мы надеемся, что наше руководство дало вам полное представление о том, как реализовать логистическую регрессию с помощью Sklearn на Python. Вы получили знания о том, что такое логистическая регрессия, как строить модели, интерпретировать результаты и некоторые основные теоретические концепции. Кроме того, мы рассмотрели такие важные темы, как несбалансированные наборы данных, точность, отзыв и матрица путаницы. Мы надеемся, что это руководство было полезным, и призываем вас продолжить изучение широкого спектра применений логистической регрессии в области Data Science.

Основные выводы из этой статьи:

  • Sklearn - популярная библиотека на Python для реализации моделей логистической регрессии.
  • Этапы предварительной обработки, такие как очистка данных, нормализация и масштабирование объектов, имеют решающее значение перед построением модели.
  • Несбалансированные наборы данных могут повлиять на точность модели, а такие методы, как избыточная и недостаточная дискретизация, могут помочь преодолеть эту проблему.
  • Оценка модели с использованием таких показателей, как точность, прецизионность, отзыв и матрица путаницы, имеет важное значение для понимания производительности модели.

Статья была взята из этого источника:

Начать дискуссию