Erkennung von Transaktionsbetrug 🕵🏻‍♂️ | von Aditya Nur Ilman W | Juni 2023

0
105


Finanzbetrug

Transaktionsbetrug ist ein ernstes Drawback, mit dem Finanzinstitute und Unternehmen im aktuellen digitalen Zeitalter konfrontiert sind. Um ihre Kunden zu schützen und finanzielle Verluste zu minimieren, müssen Unternehmen wirksame Systeme zur Betrugserkennung einführen. Herkömmliche regelbasierte Methoden reichen oft nicht aus, um auf sich ständig weiterentwickelnde Betrugsmuster zu reagieren. Daher sind ausgefeiltere und adaptivere Ansätze erforderlich. Hier werde ich meine Erkundung der Erkennung von Betrugstransaktionen mit Ihnen teilen.

Es mangelt an öffentlich zugänglichen Datensätzen zu Finanzdienstleistungen und insbesondere im aufstrebenden Bereich mobiler Geldtransaktionen. Ein Teil des Issues ist der grundsätzlich non-public Charakter von Finanztransaktionen, der dazu führt, dass keine öffentlich zugänglichen Datensätze vorliegen.

Als Ansatz für ein solches Drawback habe ich einen synthetischen Datensatz von kaggle.com verwendet, der mit dem Simulator namens PaySim generiert wurde. PaySim verwendet aggregierte Daten aus dem privaten Datensatz, um einen synthetischen Datensatz zu generieren, der dem normalen Ablauf von Transaktionen ähnelt und bösartiges Verhalten einschleust, um später die Leistung von Betrugserkennungsmethoden zu bewerten. Hier finden Sie meinen Datensatz Verknüpfung.

Pipeline

  1. Bibliothek importieren
  2. Datensatz laden
  3. Datenreinigung
  4. Explorative Datenanalyse (EDA)
  5. Explorative Datenanalyse
  6. Characteristic-Engineering
  7. Datenvisualisierung
  8. Datenvorverarbeitung
  9. Modellbau
  10. Modellbewertung
  11. Abschluss

Reisebeginn!

  1. Bibliothek importieren
import numpy as np 
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno
from scipy import stats
import plotly.categorical as px
import plotly.figure_factory as ff
from plotly.subplots import make_subplots
import plotly.graph_objs as go
plt.model.use('ggplot')

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from imblearn.mix import SMOTETomek
from collections import Counter

from sklearn.ensemble import RandomForestClassifier
from lightgbm.sklearn import LGBMClassifier
import xgboost as xgb
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression

from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score
from sklearn.metrics import classification_report
from sklearn.metrics import roc_curve, RocCurveDisplay

import warnings
warnings.filterwarnings('ignore')

2. Daten laden

fraud = pd.read_csv('..Credit_Data.csv')
fraud.head()
2.1 High-5-Datensatz
fraud.information()
2.2 Datentyp jeder Spalte

Informationen zu Schritt 2:

  • Der Datensatz besteht aus 11 Spalten.
  • Wir haben 5 Spalten vom Float-Datentyp.
  • Wir haben 3 Spalten vom ganzzahligen Datentyp.
  • Wir haben 3 Spalten des Objektdatentyps.
  • Der Datensatz enthält 6362620 Datenzeilen.

3. Datenbereinigung

Cek fehlender Wert

plt.determine(figsize = (15, 8))
msno.bar(fraud, figsize = (15,5), kind = 'ascending', colour = "#896F82")
plt.present()
3.1 Prüfung fehlender Werte

Cek doppelter Wert

fraud.duplicated().sum()

Das Ergebnis ist 0 . Es gibt kein Duplikat Wert

Ich werde die Spalte umbenennen, um es einfacher zu machen, den Namen der Spalte auf Tippfehler zu überprüfen

fraud.columns
3.2 Spalte Herkunftsname
#I modified column 'nameOrigin','oldbalanceOrg','newbalanceOrig','nameDest','oldbalanceDest','newbalanceDest', 'isFraud'
fraud = fraud.rename(columns = {'nameOrig' : 'origin', 'oldbalanceOrg' : 'sender_old_balance', 'newbalanceOrig': 'sender_new_balance', 'nameDest' : 'vacation spot', 'oldbalanceDest' : 'receiver_old_balance', 'newbalanceDest': 'receiver_new_balance', 'isFraud' : 'isfraud'})
fraud.columns
3.3 Namensspalte nach Änderung

Keine wesentlichen Spalten löschen -> „step“ und „isFlaggedFraud“

fraud = fraud.drop(columns = ['step', 'isFlaggedFraud'], axis = 'columns')

Um die Analyse komfortabler zu gestalten, verschiebe ich die Spalte „Ziel“ in die Nähe der Spalte „Ursprung“.

cols = fraud.columns.tolist()
new_position = 3

cols.insert(new_position, cols.pop(cols.index('vacation spot')))
fraud = fraud[cols]

# Examine Last Dataset
fraud.head()
3.4 Endgültiger Datensatz

Informationen zu Schritt 3:

  • In unserem Datensatz gibt es keinen Nullwert.
  • Der Datensatz enthält keine doppelten Werte.
  • Aus Gründen der Bequemlichkeit und des besseren Verständnisses haben wir einige unserer Spalten umbenannt und ihre Positionen geändert.

4. EDA

Erstellen Sie ein Balkendiagramm, um die Betrugs- und Nicht-Betrugstransaktionen in verschiedenen Transaktionstypen anzuzeigen

plt.determine(figsize = (15, 8))
ax=sns.countplot(knowledge = fraud, x = "sort", hue="isfraud", palette = 'Set1')
plt.title('Fraud and Non Fraud Transactions')
for p in ax.patches:
ax.annotate('{:.1f}'.format(p.get_height()), (p.get_x()+0.01, p.get_height()+10000))
4.1 Betrugs- und Nichtbetrugstransaktionen

Überprüfung des Herkunftsorts, von dem aus die Transaktionen getätigt wurden.

transfer_fraud = fraud[((fraud['type']=='TRANSFER') & fraud['isfraud']==1)]
transfer_fraud['origin'].value_counts()

Die Datenlänge des Ergebnisses beträgt 4097

Überprüfung des Bestimmungsorts, von dem aus die Transaktionen ausgezahlt wurden.

cash_out_fraud = fraud[(fraud['type'] == 'CASH_OUT') & (fraud['isfraud'] == 1)]
cash_out_fraud['destination'].value_counts()

Die Datenlänge des Ergebnisses beträgt 4091

Überprüfen, ob das Überweisungs- und das Empfangskonto identisch sind.

fraud_trans = fraud[fraud['isfraud'] == 1]
valid_trans = fraud[fraud['isfraud'] == 0]

trans_transfer = fraud[fraud['type'] == 'TRANSER']
trans_cashout = fraud[fraud['type'] == 'CASH_OUT']

print('Has the receiving account used for cashing out?')
trans_transfer.vacation spot.isin(trans_cashout.origin).any()

Das Ergebnis des Codes ist FALSCH. Damit ist das Transaktionskonto gemeint, für das verwendet wird Bei Betrugstransaktionen conflict das Empfangen und Senden nicht dasselbe.

Informationen zu Schritt 4:

  • Betrugstransaktionen werden in durchgeführt ÜBERWEISEN Und AUSZAHLEN Artwork der Transaktion.
  • Die Betrugstransaktionen in ÜBERWEISEN conflict 4097 Und AUSZAHLEN conflict 4091.
  • Der Betrug Transaktionen erfolgten im Allgemeinen von Kunde zu Kunde.
  • Das Transaktionskonto, für das verwendet wird Empfangen und Senden conflict nicht dasselbe im Falle von Betrugstransaktionen.

5. Characteristic-Engineering

Ich werde einen neuen Datensatz mit dem Namen „Daten“ erstellen, indem ich den Datensatz „Betrug“ kopiere. Und im Datensatz „Identify“ habe ich eine Spalte mit dem Namen „Typ2“ erstellt, die ich mit den Transaktionscodetypen „C“ für Kunde und „M“ für Händler füllen werde. Ich werde diesen Code aus den Ursprungs- und Zielspalten extrahieren.

knowledge = fraud.copy()
knowledge['type2'] = np.nan
knowledge.loc[fraud.origin.str.contains('C') & fraud.destination.str.contains('C'), 'type2'] = 'CC'
knowledge.loc[fraud.origin.str.contains('C') & fraud.destination.str.contains('M'), 'type2'] = 'CM'
knowledge.loc[fraud.origin.str.contains('M') & fraud.destination.str.contains('C'), 'type2'] = 'MC'
knowledge.loc[fraud.origin.str.contains('M') & fraud.destination.str.contains('C'), 'type2'] = 'MM'

Ändern der Spaltenposition für unsere Benutzerfreundlichkeit.

cols = knowledge.columns.tolist()
new_position = 1

cols.insert(new_position, cols.pop(cols.index('type2')))
knowledge = knowledge[cols]

Entfernen der irrelevanten Spalten -> „Origin“ und „Destinatio“

knowledge.drop(columns = ['origin','destination'], axis = 'columns', inplace = True)
knowledge.head()
5.1 Neue Daten für Characteristic Engineering

Jetzt sehen wir die Anzahl der Betrugsfälle und gültigen Transaktionen gemäß Typ 2, der angibt, ob die Transaktion von Kunde zu Kunde, Kunde zu Händler, Händler zu Kunde oder Händler zu Händler durchgeführt wurde.

fraud_trans = knowledge[data['isfraud'] == 1]
valid_trans = knowledge[data['isfraud'] == 0]

print('Variety of fraud transactions based on sort are under:n', fraud_trans.type2.value_counts(), 'n')
print('Variety of legitimate transactions based on sort are under:n', valid_trans.type2.value_counts())

Die Anzahl der Betrugstransaktionen nach Artwork ist unten aufgeführt: CC 8213

Die Anzahl der gültigen Transaktionen je nach Typ ist unten aufgeführt: CC 4202912 und CM 2151495

Schritt 5 Informationen:

  • Wir erstellen Characteristic Engineering und haben eine neue Spalte eingeführt Typ 2 das die Artwork der Transaktion zwischen enthielt Kunden und Händler.
  • Die Spaltenposition wurde angepasst und einige Spalten entfernt, die nicht mehr verwendet wurden.
  • Die Anzahl der Betrugstransaktionen insgesamt waren 8213 und wurden daraus hergestellt Kunde zu Kunde.
  • Die Anzahl der Gültige Transaktionen hergestellt aus Kunde zu Kunde Sind 4202912.
  • Die Anzahl der Gültige Transaktionen hergestellt aus Kunde zum Händler Sind 2151495.

6. Datenvisualisierung

fr = fraud_trans.type2.value_counts()
va = valid_trans.type2.value_counts()
plt.determine(figsize=(15, 8))
plt.subplot(1,2,1)
sns.countplot(x = fr)
plt.title('Fraud',fontweight="daring", dimension=20)
plt.subplot(1,2,2)
sns.countplot(x = va)
plt.title('Legitimate',fontweight="daring", dimension=20)
6.1 Betrug vs. gültige Transaktion
plt.determine(figsize = (15, 8))
ax=sns.countplot(knowledge = knowledge, x = "sort")
plt.title('Transactions based on sort')
for p in ax.patches:
ax.annotate('{:.1f}'.format(p.get_height()), (p.get_x()+0.01, p.get_height()+10000))
6.2 Artwork der Transaktion
plt.determine(figsize = (15, 8))
ax=sns.countplot(knowledge = knowledge, x = "sort")
plt.title('Transactions based on sort')
for p in ax.patches:
ax.annotate('{:.1f}'.format(p.get_height()), (p.get_x()+0.01, p.get_height()+10000))
6.3 Prozentsatz der Transaktion nach Artwork
plt.determine(figsize = (15, 8))
ax=sns.countplot(knowledge = knowledge, x = "type2", hue="isfraud", palette = 'Set1')
plt.title('Transactions based on type2')
for p in ax.patches:
ax.annotate('{:.1f}'.format(p.get_height()), (p.get_x()+0.01, p.get_height()+10000))
6.4 Geschäft nach Artwork. 2
plt.determine(figsize=(15,8))
colours = ['#006400','#008000']
plt.pie(knowledge.type2.value_counts().values,labels=knowledge.type2.value_counts().index, colours = colours, autopct='%.0f%%')
plt.title("Transactions based on type2")
plt.present()
6,5 Prozentsatz der Transaktion nach Typ2

Schritt 6 Informationen:

  • Die ersten beiden Visualisierungen enthalten die Anzahl der Transaktionen nach Transaktionstyp, Sender- und Empfängertyp.
  • Am häufigsten für Transaktionen verwendeter Transaktionstyp = AUSZAHLEN.
  • Am wenigsten verbreiteter Transaktionstyp, der für Transaktionen verwendet wird = LASTSCHRIFT.
  • Die meisten getätigten Transaktionen waren Kunde zu Kunde.

7. Datenvorverarbeitung

Lassen Sie uns die Dummies für den späteren Prozess des maschinellen Lernens erstellen. Ich verwende die Dummy-Sizzling-Codierung, da die Spalten keine bestimmte Reihenfolge haben.

knowledge = pd.get_dummies(knowledge, prefix = ['type', 'type2'], drop_first = True)

Teilen Sie den Datensatz in einen Trainings- und einen Testteil auf und führen Sie dann die Standardisierung durch.

X = knowledge.drop('isfraud', 1)
y = knowledge.isfraud

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, stratify = knowledge.isfraud)

sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.remodel(X_test)

8. Modellbau

Wir werden 4 ML-Modelle verwenden und sie trainieren. Später werden wir jedes Modell in die Liste einfügen.

rfc=RandomForestClassifier(n_estimators = 15, n_jobs = -1, random_state = 42)
lgbm = LGBMClassifier(boosting_type = 'gbdt',goal = 'binary', random_state = 8888)
xgbr = xgb.XGBClassifier(max_depth = 3, n_jobs = -1, random_state = 42, learning_rate = 0.1)
logreg = LogisticRegression(solver = 'liblinear', random_state = 42)

rfc.match(X_train, y_train)
lgbm.match(X_train, y_train)
xgbr.match(X_train, y_train)
logreg.match(X_train, y_train)

classifiers = []
classifiers.append(rfc)
classifiers.append(lgbm)
classifiers.append(xgbr)
classifiers.append(logreg)

Lassen Sie uns die Vorhersage durchführen und sowohl die Genauigkeit als auch die Fläche unter der Kurve (AUC) jedes Modells ermitteln.

accuracy_list = []
auc_list = []

for classifier in classifiers:
y_pred = classifier.predict(X_test)
y_pred_proba = classifier.predict_proba(X_test)[:,1]
accuracy_list.append(accuracy_score(y_test, y_pred))
auc_list.append(roc_auc_score(y_test, y_pred_proba))

accuracy_dict = {}
auc_dict = {}
for i in vary(4):
key=['Random Forest', 'Light GBM', 'XGBoost','LR'][i]
accuracy_dict[key] = accuracy_list[i]
auc_dict[key] = auc_list[i]

accuracy_dict_sorted = dict(sorted(accuracy_dict.objects(), key = lambda merchandise: merchandise[1]))
auc_dict_sorted = dict(sorted(auc_dict.objects(), key = lambda merchandise: merchandise[1]))

Erstellen Sie eine Funktion für den Visualisierungsteil.

def px_bar(x,y,textual content,title,colour,color_discrete_sequence):
return px.bar(x = x, y = y, textual content = textual content, title = title, colour = colour, color_discrete_sequence=color_discrete_sequence)
fig = px_bar(record(accuracy_dict_sorted.keys()), record(accuracy_dict_sorted.values()), np.spherical(record(accuracy_dict_sorted.values()),3), 'Accuracy rating of every classifiers', record(accuracy_dict_sorted.keys()), px.colours.sequential.matter)
for idx in [2,3]:
fig.knowledge[idx].marker.line.width = 3
fig.knowledge[idx].marker.line.colour = "black"
fig.present()
8.1 Genauigkeitsbewertung jedes Modells
fig = px_bar(record(auc_dict_sorted.keys()), record(auc_dict_sorted.values()), np.spherical(record(auc_dict_sorted.values()),3), 'AUC rating of every classifiers', record(auc_dict_sorted.keys()), px.colours.sequential.matter)

for idx in [2,3]:
fig.knowledge[idx].marker.line.width = 3
fig.knowledge[idx].marker.line.colour = "black"
fig.present()

8,2 AUC-Rating jedes Modells

9. Modellbewertung

Lassen Sie uns noch einmal unser bestes Modell trainieren. -> Zufälliger Wald

rfc=RandomForestClassifier(n_estimators = 15, n_jobs = -1, random_state = 42)
rfc.match(X_train, y_train)

rfc_pred = rfc.predict(X_test)
rfc_pred_proba = rfc.predict_proba(X_test)[:,1]

print(classification_report(y_test, rfc_pred, target_names=['Not Fraud','Fraud']))
9.1 Modellbewertung Random Forest

Unten wird die AUC angezeigt, um die Leistung von Randome Forest zu zeigen.

fpr, tpr, temp = roc_curve(y_test, rfc_pred_proba)
auc = spherical(roc_auc_score(y_test, rfc_pred_proba),3)
plt.determine(figsize=(15,7))
plt.plot(fpr,tpr,label='Random Forest Classifier, AUC='+str(auc),linestyle='stable',colour='#800000')
plt.plot([0, 1], [0, 1], colour = 'g')
plt.title('ROC Curve')
plt.legend(loc='higher proper')
9.2 AUC-Kurven-Zufallswald

10. Fazit

Die Gesamtzahl der Betrugstransaktionen betrug 8213 aus 6362620 Transaktionen. Diese Betrugstransaktionen waren entweder AUSZAHLEN oder LASTSCHRIFT und wurden aus a Kunde zu Kunde Konto. Wir haben 4 Algorithmen trainiert und Zufälliger Wald schnitten unter ihnen am besten ab. Der Wert von ReaCall beträgt 0,8. Dies bedeutet, dass das Modell in der Lage ist, etwa 80 % aller Daten, die einen Betrugswert ergeben, als wahr positiv zu erkennen. Und es gab das AUC-Rating von 0,9, tDies deutete darauf hin, dass das Modell über eine äußerst effektive Fähigkeit verfügt, zwischen positiven und negativen Klassen zu unterscheiden. Dies bedeutet, dass das Modell tendenziell den Stichproben aus der positiven Klasse höhere Werte zuweist als den Stichproben aus der negativen Klasse. Im Anwendungskontext ein Modell mit einem AUC von 0,9 wird eine sehr starke Vorhersagefähigkeit zugeschrieben.

Die Erkennung von Transaktionsbetrug spielt eine entscheidende Rolle beim Schutz von Finanzinstituten und Unternehmen vor potenziellen Verlusten. Durch den Einsatz fortschrittlicher Techniken wie künstlicher Intelligenz und maschinellem Lernen können Unternehmen ihre Fähigkeit verbessern, betrügerische Aktivitäten zu erkennen und zu verhindern. Die Bewertungsmetriken Präzision, Rückruf und F1-Rating liefern wertvolle Einblicke in die Leistung des Modells und ermöglichen eine kontinuierliche Verbesserung und Optimierung. Angesichts der sich ständig weiterentwickelnden Landschaft des Transaktionsbetrugs ist es für die Aufrechterhaltung eines sicheren und vertrauenswürdigen Finanzökosystems von entscheidender Bedeutung, proaktiv zu bleiben und progressive Ansätze zu nutzen. Durch die Implementierung robuster Betrugserkennungssysteme können wir die Integrität und Zuverlässigkeit von Transaktionen gewährleisten und letztendlich ein sichereres Umfeld für Unternehmen und Kunden gleichermaßen schaffen.

Wie auch immer, vielen Dank, dass Sie den ganzen Weg hierher gegangen sind und sich die Zeit genommen haben, dies zu lesen! . Geben Sie mir unten einen Kommentar, um meinen Artikel für die Zukunft zu verbessern.

Ihr könnt unten gerne einige Projektideen kommentieren, die ich umsetzen könnte, und ich werde sie berücksichtigen!

Zögern Sie nicht, mich anzumachen Linkedin , Github oder Email,: adityanurilmanw@gmail.com . Lass uns verbinden!



Source link

HINTERLASSEN SIE EINE ANTWORT

Please enter your comment!
Please enter your name here