行业案例 | 数据分析在银行业应用之欺诈检测

2022-04-07     CDA数据分析师

原标题:行业案例 | 数据分析在银行业应用之欺诈检测

CDA数据分析师 出品

作者:Elena Kosourova

编译:Mika

在本文中我们将通过探索一个很常见的用例——欺诈检测,从而了解数据分析在银行业是如何运用的。

背景介绍

银行业 是最早应用数据科学技术的领域之一,收集了大量结构化数据。

那么,数据分析是如何应用于银行业的呢?

如今,数据已经成为银行业最宝贵的资产,不仅可以帮助银行吸引更多的客户,提高现有客户的忠诚度,做出更有效的数据驱动的决策,还可以增强业务能力,提高运营效率,改善现有的服务,加强安全性,并通过所有这些行动获得更多的收入等等。

因此,当下大部分数据相关工作需求来自银行业,这并不令人惊讶。

数据分析使银行业能够成功地执行众多任务,包括:

  • 投资风险分析
  • 客户终身价值预测
  • 客户细分
  • 客户流失率预测
  • 个性化营销
  • 客户情绪分析
  • 虚拟助理和聊天机器人 ……

下面,我们将仔细看看银行业中最常见的数据分析用例之一。

数据分析在银行业应用案例:欺诈检测

除了银行业,欺诈活动还存在于许多领域。在政府、保险、公共部门、销售和医疗保健等领域,这都是一个具有挑战性的问题。也就是说,任何处理大量在线交易的企业都会面临欺诈风险。

金融犯罪的形式多种多样,包括欺诈性信用卡交易、伪造银行支票、逃税、网络攻击、客户账户盗窃、合成身份、诈骗等。

其主要分析技术可分为两组:

  • 统计学: 统计参数计算、回归、概率分布、数据匹配
  • 人工智能(AI): 数据挖掘、机器学习、深度学习

机器学习是欺诈检测的重要支柱,其工具包提供了两种方法:

  • 监督方法 :K-近邻、逻辑回归、支持向量机、决策树、随机森林、时间序列分析、神经网络等。

目前还没有通用的机器学习算法用于欺诈检测。相反,对于现实世界的数据科学用例,通常会测试几种技术或其组合,计算模型的预测准确性,并选择最佳方法。

欺诈检测系统的主要挑战是迅速适应不断变化的欺诈模式和欺诈者的策略,并及时发现新的和日益复杂的方案。欺诈案件总是占少数,并且很好地隐藏在真实的交易中。

下面来探讨一下使用Python进行信用卡欺诈检测。

我们将用到 creditcard_data 数据集。

Credit Card Fraud Detection | Kaggle数据集:

https://www.kaggle.com/mlg-ulb/creditcardfraud

该数据集是Kaggle信用卡欺诈检测数据集的一个修改样本。原始数据代表了2013年9月两天内欧洲持卡人拥有信用卡的交易情况。

让我们读入数据并快速浏览一下。

importpandas aspd

creditcard_data = pd.read_csv( 'creditcard_data.csv', index_col= 0)

print(creditcard_data.info)

print( '\n')

pd.options.display.max_columns = len(creditcard_data)

print(creditcard_data.head( 3))

< class'pandas.core.frame.DataFrame'>

Int64Index: 5050entries, 0to5049

Data columns (total 30columns):

# Column Non- NullCount Dtype

--- ------ -------------- -----

0V1 5050non- nullfloat64

1V2 5050non- nullfloat64

2V3 5050non- nullfloat64

3V4 5050non- nullfloat64

4V5 5050non- nullfloat64

5V6 5050non- nullfloat64

6V7 5050non- nullfloat64

7V8 5050non- nullfloat64

8V9 5050non- nullfloat64

9V10 5050non- nullfloat64

10V11 5050non- nullfloat64

11V12 5050non- nullfloat64

12V13 5050non- nullfloat64

13V14 5050non- nullfloat64

14V15 5050non- nullfloat64

15V16 5050non- nullfloat64

16V17 5050non- nullfloat64

17V18 5050non- nullfloat64

18V19 5050non- nullfloat64

19V20 5050non- nullfloat64

20V21 5050non- nullfloat64

21V22 5050non- nullfloat64

22V23 5050non- nullfloat64

23V24 5050non- nullfloat64

24V25 5050non- nullfloat64

25V26 5050non- nullfloat64

26V27 5050non- nullfloat64

27V28 5050non- nullfloat64

28Amount 5050non- nullfloat64

29Class5050non- nullint64

dtypes: float64( 29), int64( 1)

memory usage: 1.2MB

V1 V2 V3 V4 V5 V6 V7 \

01.725265-1.337256-1.012687-0.361656-1.431611-1.098681-0.842274

10.683254-1.6818750.533349-0.326064-1.4556030.101832-0.520590

21.067973-0.6566671.0297380.253899-1.1727150.073232-0.745771

V8 V9 V10 V11 V12 V13 V14 \

0-0.026594-0.0324090.2151131.618952-0.654046-1.442665-1.546538

10.114036-0.6017600.4440111.5215700.499202-0.127849-0.237253

20.2498031.383057-0.483771-0.7827800.005242-1.273288-0.269260

V15 V16 V17 V18 V19 V20 V21 \

0-0.2300081.7855391.4197930.0716660.2330310.2759110.414524

1-0.7523510.6671900.724785-1.7366150.7020880.6381860.116898

20.091287-0.3479730.495328-0.9259490.099138-0.083859-0.189315

V22 V23 V24 V25 V26 V27 V28 \

00.7934340.0288870.419421-0.367529-0.155634-0.0157680.010790

1-0.304605-0.1255470.2448480.069163-0.460712-0.0170680.063542

2-0.4267430.0795390.1296920.0027780.970498-0.0350560.017313

Amount Class

0189.000

1315.170

259.980

数据集包含以下变量:

  • 数值编码的变量V1到V28是从PCA变换中获得的主分量。由于保密问题,未提供有关原始功能的背景信息。
  • Amount变量表示交易金额。
  • Class变量显示交易是否为欺诈(1)或非欺诈(0)。

幸运的是,就其性质而言,欺诈事件在任何交易列表中都是极少数。然而,当数据集中包含的不同类别或多或少存在时,机器学习算法通常效果最好。否则,就没有什么数据可供借鉴,这个问题被称为类别不均。

接着计算欺诈交易占数据集中交易总数的百分比:

round(creditcard_data[ 'Class'].value_counts* 100/ len(creditcard_data)).convert_dtypes

099

11

Name: Class, dtype: Int64

并创建一个图表,将欺诈与非欺诈的数据点可视化。

importmatplotlib.pyplot asplt

importnumpy asnp

defprep_data(df):

X = df.iloc[:, 1: 28]

X = np.array(X).astype(float)

y = df.iloc[:, 29]

y = np.array(y).astype(float)

returnX, y

defplot_data(X, y):

plt.scatter(X[y== 0, 0], X[y== 0, 1], label= 'Class #0', alpha= 0.5, linewidth= 0.15)

plt.scatter(X[y== 1, 0], X[y== 1, 1], label= 'Class #1', alpha= 0.5, linewidth= 0.15, c= 'r')

plt.legend

returnplt.show

X, y = prep_data(creditcard_data)

plot_data(X, y)

可以确认的是,欺诈性交易的比例非常低,当中存在一个类别不平衡问题的案例。

为了解决这个问题,我们可以使用合成少数人超抽样技术(SMOTE)来重新平衡数据。与随机超额取样不同,SMOTE稍微复杂一些,因为它不只是创建观察值的精确副本。

相反,它使用欺诈案件的最近邻居的特征来创建新的、合成的样本,这些样本与少数人类别中的现有观察值相当相似,让我们把SMOTE应用于该信用卡数据。

fromimblearn.over_sampling importSMOTE

method = SMOTE

X_resampled, y_resampled = method.fit_resample(X, y)

plot_data(X_resampled, y_resampled)

正如所看到的,使用SMOTE突然提供了更多的少数类别的观察结果。为了更好地看到这种方法的结果,这里将把其与原始数据进行比较。

defcompare_plot(X, y, X_resampled, y_resampled, method):

f, (ax1, ax2) = plt.subplots( 1, 2)

c0 = ax1.scatter(X[y== 0, 0], X[y== 0, 1], label= 'Class #0',alpha= 0.5)

c1 = ax1.scatter(X[y== 1, 0], X[y== 1, 1], label= 'Class #1',alpha= 0.5, c= 'r')

ax1.set_title( 'Original set')

ax2.scatter(X_resampled[y_resampled== 0, 0], X_resampled[y_resampled== 0, 1], label= 'Class #0', alpha= .5)

ax2.scatter(X_resampled[y_resampled== 1, 0], X_resampled[y_resampled== 1, 1], label= 'Class #1', alpha= .5,c= 'r')

ax2.set_title(method)

plt.figlegend((c0, c1), ( 'Class #0', 'Class #1'), loc= 'lower center', ncol= 2, labelspacing= 0.)

plt.tight_layout(pad= 3)

returnplt.show

print( f'Original set:\n'

f' {pd.value_counts(pd.Series(y))}\n\n'

f'SMOTE:\n'

f' {pd.value_counts(pd.Series(y_resampled))}\n' )

compare_plot(X, y, X_resampled, y_resampled, method= 'SMOTE')

Originalset:

0 .05000

1 .050

dtype: int64

SMOTE:

0 .05000

1 .05000

dtype: int64

因此,SMOTE方法已经完全平衡了数据,少数群体现在与多数群体的规模相等。

例如,此类规则可能涉及不寻常的交易地点或可疑的频繁交易。其想法是基于常见的统计数据定义阈值,通常是基于观察值的平均值,并在功能上使用这些阈值来检测欺诈。

print(creditcard_data.groupby( 'Class').mean.round( 3) [['V1', 'V3']])

V1V3

Class

0 0 .0350 .037

1 -4.985-7.294

在特殊情况下,可以应用以下条件:V1<-3和V3<-5。然后,为了评估这种方法的性能,我们将把标记的欺诈案例与实际案例进行比较:

creditcard_data[ 'flag_as_fraud'] = np.where(np.logical_and(creditcard_data[ 'V1']<-3, creditcard_data[ 'V3']<-5), 1, 0)

print(pd.crosstab(creditcard_data[ 'Class'], creditcard_data[ 'flag_as_fraud'], rownames=[ 'Actual Fraud'], colnames=[ 'Flagged Fraud']))

FlaggedFraud 01

Actual Fraud

0498416

12822

fromsklearn.model_selection importtrain_test_split

fromsklearn.linear_model importLogisticRegression

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size= 0.3, random_state= 0)

lr = LogisticRegression

lr.fit(X_train, y_train)

predictions = lr.predict(X_test)

print(pd.crosstab(y_test, predictions, rownames=[ 'Actual Fraud'], colnames=[ 'Flagged Fraud']))

FlaggedFraud0 .01 .0

ActualFraud

0 .01504 1

1 .01 9

需要注意的是,在混淆矩阵中要查看的观测值较少,因为我们只使用测试集来计算模型结果,即仅占整个数据集的30%。

结果是发现了更高比例的欺诈案件:90%(9/10),而之前的结果是44%(22/50),得到的误报也比以前少了很多,这是一个进步。

现在让我们回到前面讨论的类不平衡问题,并探索是否可以通过将逻辑回归模型与SMOTE重采样方法相结合来进一步提高预测结果。为了高效、一次性地完成这项工作,我们需要定义一个管道,并在数据上运行:

from imblearn.pipeline import Pipeline

# Defining which resampling method and which ML model to use in the pipeline

resampling = SMOTE

lr = LogisticRegression

pipeline = Pipeline([('SMOTE', resampling), ('Logistic Regression', lr)])

pipeline.fit(X_train, y_train)

predictions = pipeline.predict(X_test)

print(pd.crosstab(y_test, predictions, rownames=['Actual Fraud'], colnames=['Flagged Fraud']))

FlaggedFraud0 .01 .0

ActualFraud

0 .01496 9

1 .01 9

可以看到,在案例中,SMOTE并没有带来任何改进:仍然捕获了90%的欺诈事件,而且假阳性数量略高。

这里的解释是,重新取样不一定在所有情况下都能带来更好的结果。当欺诈案件在数据中非常分散时,其最近的不一定也是欺诈案件,所以使用SMOTE会引入偏见问题。

为了提高逻辑回归模型的准确性,我们可以调整一些算法参数,也可以考虑采用K-fold交叉验证法,而不是直接将数据集分成两部分。

最后,还可以尝试一些其他的机器学习算法(如决策树或随机森林),看看它们是否能给出更好的结果。

参考链接:

https://www.datacamp.com/blog/data-science-in-banking

好,以上就是今天的分享。如果大家还有数据分析方面相关的疑问,就在评论区留言。

更多精彩案例敬请关注4月7日直播,现在扫码免费预约~

直播预告

预约直播

点这里关注我,记得标星哦~

CDA课程咨询

文章来源: https://twgreatdaily.com/zh-hans/7530b214e097a4691d6e5f311d56be1a.html