please select a valid python_Python实战金融交易欺诈检测

本次用到的数据来自于Kaggle网站中的Synthetic Financial Datasets For Fraud Detection项目,该项目旨在分析检测金融欺诈,其数据集来自某移动支付公司的交易日志,我们的目的是根据交易记录数据判断该笔交易是否为欺诈行为,数据集地址如下:https://www.kaggle.com/ntnu-testimon/paysim1​www.kaggle.com

本项目共包含六百多万条数据,反应了银行每一笔款项的记录。每条数据包含十一个字段,分别为:step(每一步代表1个小时的时间,总共包含744步(模拟30天))

type(交易类型,包含转账、取现等)

amount(交易金额)

nameOrig(转出账户)

oldbalanceOrg/newbalanceOrig(转出账户的前后余额)

nameDest(转入账户)

oldbalanceDest/newbalanceDest(转入账户的前后余额)

isFraud(代表欺诈行为)

isFlaggedFraud(银行系统模型判断的欺诈标签,原数据集解释为只有转账额超过200.000的标注)

通过对数据的预处理和特征分析等步骤,最后使用LogisticRegression算法对数据进行二分类预测,画出ROC曲线并计算AUC值,结果表明对本项目的处理较好。 本文基于对kaggle比赛的初体验,主要是为了加深对Python语法的理解和实际应用,在模型和算法等方面上没有进行深入的研究分析。

1.Import Packages

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import warnings

warnings.filterwarnings('ignore')

%matplotlib inline

import seaborn as sns

from sklearn import preprocessing

from sklearn.model_selection import train_test_split

from sklearn.linear_model import LogisticRegression

from sklearn.metrics import roc_curve,auc

2.Import Dataset

dataset_path="C:\\Users\\KIN\\Desktop\\kaggle dataset\\Fraud Detection.csv"

data=pd.read_csv(dataset_path)

data.head(10)

data.info()

data.describe()

3.Exploratory Data Analysis

data.groupby(['type','isFraud']).size().plot(kind='bar')发现诈骗只发生在转账和取现两种交易方法中

data.loc[data['isFlaggedFraud']==1].type.value_counts()

data.loc[data['isFlaggedFraud']==1]被银行系统标记的诈骗只有16条并且都是transfer形式,并且被标记的诈骗必然是诈骗

考虑到诈骗往往都会有一个金额下限,即小额诈骗的收益过低,因此探究交易金额的影响。同时考虑到诈骗一般会把账户内存款都给骗取干净,诈骗青睐于转出账户中有大额存款的,转入账户为犯罪提现用账户,因此转入账户前余额应该很低甚至为0,基于以上考虑进行下面探究。

fig, axs = plt.subplots(2, 2, figsize=(10, 10))

sns.boxplot(x='isFraud',y='amount',hue='type',data=data_select,ax=axs[0][0])

axs[0][0].set_yscale('log')

sns.scatterplot(x='oldbalanceOrg', y='amount', data=data_select[data_select['isFraud'] ==1], ax=axs[0][1])

sns.boxplot(x='isFraud',y='oldbalanceOrg',hue='type',data=data_select,ax=axs[1][0])

axs[1][0].set(ylim=(0, 5e7))

sns.boxplot(x='isFraud',y='oldbalanceDest',hue='type',data=data_select,ax=axs[1][1])

axs[1][1].set(ylim=(0, 3e7))

plt.show()结果发现诈骗金额确实有集中性,但是考虑到非诈骗转账中金额也有集中性且相近,因此amount字段没有明显的代表性。有趣的是发现转出账户余额低于1e7时,余额被完全诈骗干净。但是随着余额的增加,诈骗金额保持在1e7,这个无法理解。诈骗集中发生在转出账户余额较低的账户中,这点跟预期不同。诈骗发生时转入账户前余额普遍极低,这点复合诈骗犯避免查封账户,尽量选择空置账户的考虑

sns.scatterplot(x='oldbalanceOrg', y='amount', data=data_select[data_select['isFraud'] ==0])

plt.show()交易金额存在超过1e7数量级的,但诈骗金额不超过1e7

数据集解释账户类型以M开头的是商家账户,那C开头的应该是Customer客户

data_Fraud =data.loc[data.isFraud == 1]

data_NotFraud = data.loc[data.isFraud == 0]

print("转出账户(诈骗)为C类型:",len(data_Fraud.loc[data_Fraud.nameOrig.str.contains('C')]))

print("转出账户(诈骗)为M类型:",len(data_Fraud.loc[data_Fraud.nameOrig.str.contains('M')]))

print("转入账户(诈骗)为C类型:",len(data_Fraud.loc[data_Fraud.nameDest.str.contains('C')]))

print("转入账户(诈骗)为M类型:",len(data_Fraud.loc[data_Fraud.nameDest.str.contains('M')]))

print("转出账户(非诈骗)为C类型:",len(data_NotFraud.loc[data_NotFraud.nameOrig.str.contains('C')]))

print("转出账户(非诈骗)为M类型:",len(data_NotFraud.loc[data_NotFraud.nameOrig.str.contains('M')]))

print("转入账户(非诈骗)为C类型:",len(data_NotFraud.loc[data_NotFraud.nameDest.str.contains('C')]))

print("转入账户(非诈骗)为M类型:",len(data_NotFraud.loc[data_NotFraud.nameDest.str.contains('M')]))所以诈骗只发生在接受账户为C类型的交易中一般在诈骗后,接受账户应该会把钱转出来,因此查看诈骗中收款人和提现人是否有重复。但结果证明不存在这种账户,step代表的先转账后提现的逻辑也没有体现出来

#因此去掉没用的特征数据列

data_select.drop(['step','nameOrig','nameDest','isFlaggedFraud'],axis=1,inplace=True)

#重新设置索引

data_select.reset_index()

#将type转换成类别数据,即0, 1

data_select.loc[data_select.type=='TRANSFER','type'] = 0

data_select.loc[data_select.type=='CASH_OUT','type'] = 1

4 可视化

data_select['type'].value_counts()

sns.heatmap(data_select.corr())

5 数据建模

data_select['isFraud'].value_counts()发现数据严重不平衡,会造成模型对二者的拟合程度差异

通常我们会参考小众类的数量,在大众类中采样,这称为undersampling.因此在正样本中随机选取8213个样本.

nonfraud_index=data_select.loc[data_select.isFraud==0].index

random_nonfraud_index=np.random.choice(nonfraud_index,size=8213,replace=False)

Fraud_index=data_select.loc[data_select.isFraud==1].index

undersampling_index=np.concatenate([Fraud_index,random_nonfraud_index])

undersampling_data=data_select.loc[data_select.index.isin(undersampling_index)]

x_undersampling=undersampling_data[['type','amount','oldbalanceOrg','newbalanceOrig','oldbalanceDest','newbalanceDest']]

y_undersampling=undersampling_data['isFraud']

x_train, x_test, y_train, y_test=train_test_split(x_undersampling, y_undersampling, test_size=0.25, random_state=0,stratify=x_undersampling.type)

modle=LogisticRegression().fit(x_train,y_train)

pred_score=modle.predict_proba(x_test)

fpr, tpr, thresholds = roc_curve(y_test,pred_score[:, 1])

AUC=auc(fpr,tpr)

plt.plot(fpr,tpr,label='AUC = %0.2f'% AUC)

plt.legend(loc='lower right')

plt.title('Receiver Operating Characteristic')

plt.plot([0,1],[0,1],'r--')

plt.ylabel('True Positive Rate')

plt.xlabel('False Positive Rate')

ROC和AUC值的定义

ROC的全名叫做Receiver Operating Characteristic,其主要分析工具是一个画在二维平面上的曲线——ROC curve。平面的横坐标是false positive rate(FPR),纵坐标是true positive rate(TPR)。AUC(Area Under roc Curve)值为ROC曲线所覆盖的区域面积,通常,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的performance。AUC = 1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

而在本文中,AUC=0.98接近1,说明模型的预测效果较好。

TPR代表在所有正样本中,即实际标签为1的样本中,最终被预测为1的比率;FPR代表在所有负样本中,即实际标签为0的样本中,最终被预测为1的比率;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值