Обнаружение мошенничества с кредитными картами — нейронные сети и выборка SMOTE
О наборе данных
«Наборы данных содержат транзакции, совершенные по кредитным картам в сентябре 2013 года держателями карт из Европы. Этот набор данных представляет транзакции, которые произошли за два дня, где у нас есть 492 мошенничества из 284 807 транзакций. Набор данных сильно несбалансирован, на положительный класс (мошенничество) приходится 0,172% всех транзакций.
Он содержит только числовые входные переменные, которые являются результатом преобразования PCA. К сожалению, из соображений конфиденциальности мы не можем предоставить исходные функции и дополнительную справочную информацию о данных. Признаки V1, V2, … V28 являются основными компонентами, полученными с помощью PCA, единственные признаки, которые не были преобразованы с помощью PCA, — это «Время» и «Количество». Функция «Время» содержит секунды, прошедшие между каждой транзакцией и первой транзакцией в наборе данных. Функция «Сумма» — это сумма транзакции, эту функцию можно использовать, например, для зависимого от затрат обучения. Функция «Класс» — это переменная ответа, которая принимает значение 1 в случае мошенничества и 0 в противном случае».
Импорт библиотек
import numpy as np import pandas as pd import keras import matplotlib.pyplot as plt import seaborn as sns
Читать и исследовать данные
df = pd.read_csv("../input/creditcard.csv") # First 5 rows of data df.head()
df.info()
df.columns
Нормализация «Сумма»
from sklearn.preprocessing import StandardScaler df['Amount(Normalized)'] = StandardScaler().fit_transform(df['Amount'].values.reshape(-1,1)) df.iloc[:,[29,31]].head()
df = df.drop(columns = ['Amount', 'Time'], axis=1) # This columns are not necessary anymore.
Предварительная обработка данных
X = df.drop('Class', axis=1) y = df['Class']
Поезд-тестовый сплит
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) # We are transforming data to numpy array to implementing with keras X_train = np.array(X_train) X_test = np.array(X_test) y_train = np.array(y_train) y_test = np.array(y_test)
Искусственные нейронные сети
from keras.models import Sequential from keras.layers import Dense, Dropout model = Sequential([ Dense(units=20, input_dim = X_train.shape[1], activation='relu'), Dense(units=24,activation='relu'), Dropout(0.5), Dense(units=20,activation='relu'), Dense(units=24,activation='relu'), Dense(1, activation='sigmoid') ]) model.summary()
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(X_train, y_train, batch_size=30, epochs=5)
score = model.evaluate(X_test, y_test) print('Test Accuracy: {:.2f}%\nTest Loss: {}'.format(score[1]*100,score[0]))
from sklearn.metrics import confusion_matrix, classification_report y_pred = model.predict(X_test) y_test = pd.DataFrame(y_test) cm = confusion_matrix(y_test, y_pred.round()) sns.heatmap(cm, annot=True, fmt='.0f', cmap='cividis_r') plt.show()
Наши результаты в порядке, однако это не лучший способ делать такие вещи. Поскольку наш набор данных несбалансирован (у нас 492 случая мошенничества из 284 807 транзакций), мы будем использовать выборку методом выборки. По сути, лучше всего превратить наши несбалансированные данные в сбалансированные. Для краткого объяснения вы можете проверить ссылку: http://rikunert.com/SMOTE_explained
Выборка SMOTE
from imblearn.over_sampling import SMOTE X_smote, y_smote = SMOTE().fit_sample(X, y) X_smote = pd.DataFrame(X_smote) y_smote = pd.DataFrame(y_smote) y_smote.iloc[:,0].value_counts()
X_train, X_test, y_train, y_test = train_test_split(X_smote, y_smote, test_size=0.3, random_state=0) X_train = np.array(X_train) X_test = np.array(X_test) y_train = np.array(y_train) y_test = np.array(y_test) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(X_train, y_train, batch_size = 30, epochs = 5)
score = model.evaluate(X_test, y_test) print('Test Accuracy: {:.2f}%\nTest Loss: {}'.format(score[1]*100,score[0]))
y_pred = model.predict(X_test) y_test = pd.DataFrame(y_test) cm = confusion_matrix(y_test, y_pred.round()) sns.heatmap(cm, annot=True, fmt='.0f') plt.show()
Это неправильный результат, потому что мы использовали данные с точной выборкой, потому что количество классов 0 и класса 1 здесь равно. Вот почему мы будем использовать все данные, которые мы импортировали в начале.
y_pred2 = model.predict(X) y_test2 = pd.DataFrame(y) cm2 = confusion_matrix(y_test2, y_pred2.round()) sns.heatmap(cm2, annot=True, fmt='.0f', cmap='coolwarm') plt.show()
scoreNew = model.evaluate(X, y) print('Test Accuracy: {:.2f}%\nTest Loss: {}'.format(scoreNew[1]*100,scoreNew[0]))
print(classification_report(y_test2, y_pred2.round()))
Спасибо за уделенное время!
LinkedIn: https://www.linkedin.com/in/canerdabakoglu/
GitHub: https://github.com/cdabakoglu