常见的数据分析用例 —— 信用卡交易欺诈检测

文章目录

  • 引言
  • 数据集
  • 分析
    • 1. 读入数据并快速浏览
    • 2.计算欺诈交易占数据集中交易总数的百分比
    • 3. 类别不平衡对模型的影响
      • 3.1 总体思路
        • (1)数据的划分
        • (2)训练模型
        • (3)测试模型
        • (4)解决不平衡问题
      • 3.2 为什么要解决不平衡问题
    • 4. 处理不平衡数据集
    • 5. 训练和评估模型
      • 5.1 回到原始数据,制定规则
        • 5.1.1 代码
      • 5.1.2 结果分析
        • 混淆矩阵
        • 分类报告
      • 结论
      • 5.2 逻辑回归模型(未使用SMOTE)和逻辑回归模型(使用SMOTE)
        • 代码及结果
          • 混淆矩阵
          • 分类报告
    • 6. 进一步
    • 7. 随机森林模型
    • 8. 模型应用
      • 误报处理
      • 漏报处理

引言

数据分析在银行中的应用有如下:
投资风险分析
客户终身价值预测
客户细分
客户流失率预测
个性化营销
客户情绪分析
虚拟助理和聊天机器人
……
这里是一个常见的数据分析用例

欺诈检测是为识别和防止欺诈活动以及财务损失而采取的一种主动措施
一般的做法有:

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

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

  • 监督方法:K-近邻、逻辑回归、支持向量机、决策树、随机森林、时间序列分析、神经网络等。
  • 无监督方法:聚类分析、链接分析、自组织地图、主成分分析、异常识别等。

目前没有通用的机器学习算法用于欺诈检测。相反,对于现实世界的数据科学用例,通常会选择几种方法,通过测试比较,选择最佳的。

数据集

Credit Card Fraud Detection | Kaggle数据集:
https://www.kaggle.com/mlg-ulb/creditcardfraud

该数据集是Kaggle信用卡欺诈检测数据集的一个修改样本,持卡人拥有信用卡的交易情况

下载以后保存在Jupyter notebook默认目录下
在这里插入图片描述

分析

1. 读入数据并快速浏览

import pandas as pd

creditcard_data = pd.read_csv('creditcard.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'>
Index: 284807 entries, 0.0 to 172792.0
Data columns (total 30 columns):
 #   Column  Non-Null Count   Dtype  
---  ------  --------------   -----  
 0   V1      284807 non-null  float64
 1   V2      284807 non-null  float64
 2   V3      284807 non-null  float64
 3   V4      284807 non-null  float64
 4   V5      284807 non-null  float64
 5   V6      284807 non-null  float64
 6   V7      284807 non-null  float64
 7   V8      284807 non-null  float64
 8   V9      284807 non-null  float64
 9   V10     284807 non-null  float64
 10  V11     284807 non-null  float64
 11  V12     284807 non-null  float64
 12  V13     284807 non-null  float64
 13  V14     284807 non-null  float64
 14  V15     284807 non-null  float64
 15  V16     284807 non-null  float64
 16  V17     284807 non-null  float64
 17  V18     284807 non-null  float64
 18  V19     284807 non-null  float64
 19  V20     284807 non-null  float64
 20  V21     284807 non-null  float64
 21  V22     284807 non-null  float64
 22  V23     284807 non-null  float64
 23  V24     284807 non-null  float64
 24  V25     284807 non-null  float64
 25  V26     284807 non-null  float64
 26  V27     284807 non-null  float64
 27  V28     284807 non-null  float64
 28  Amount  284807 non-null  float64
 29  Class   284807 non-null  int64  
dtypes: float64(29), int64(1)
memory usage: 67.4 MB
None


            V1        V2        V3        V4        V5        V6        V7  \
Time                                                                         
0.0  -1.359807 -0.072781  2.536347  1.378155 -0.338321  0.462388  0.239599   
0.0   1.191857  0.266151  0.166480  0.448154  0.060018 -0.082361 -0.078803   
1.0  -1.358354 -1.340163  1.773209  0.379780 -0.503198  1.800499  0.791461   

            V8        V9       V10       V11       V12       V13       V14  \
Time                                                                         
0.0   0.098698  0.363787  0.090794 -0.551600 -0.617801 -0.991390 -0.311169   
0.0   0.085102 -0.255425 -0.166974  1.612727  1.065235  0.489095 -0.143772   
1.0   0.247676 -1.514654  0.207643  0.624501  0.066084  0.717293 -0.165946   

           V15       V16       V17       V18       V19       V20       V21  \
Time                                                                         
0.0   1.468177 -0.470401  0.207971  0.025791  0.403993  0.251412 -0.018307   
0.0   0.635558  0.463917 -0.114805 -0.183361 -0.145783 -0.069083 -0.225775   
1.0   2.345865 -2.890083  1.109969 -0.121359 -2.261857  0.524980  0.247998   

           V22       V23       V24       V25       V26       V27       V28  \
Time                                                                         
0.0   0.277838 -0.110474  0.066928  0.128539 -0.189115  0.133558 -0.021053   
0.0  -0.638672  0.101288 -0.339846  0.167170  0.125895 -0.008983  0.014724   
1.0   0.771679  0.909412 -0.689281 -0.327642 -0.139097 -0.055353 -0.059752   

      Amount  Class  
Time                 
0.0   149.62      0  
0.0     2.69      0  
1.0   378.66      0  

这个数据集共有284807条记录。
数据集包含30个列,其中29个列是float64类型(浮点数),1个列是int64类型(整数)。
每一列的数据都是非空的(没有缺失值)。

通过creditcard_data.head(3),我们查看数据集的前3行:
Time:表示交易时间。
V1 到 V28:这些是经过PCA(主成分分析)转换后的特征
Amount:表示交易金额。
Class:目标变量,表示交易是否为欺诈(1表示欺诈,0表示正常)。

数据集非常大且没有缺失值,适合进行机器学习模型的训练。

通过初步的浏览,我们对数据有了一个基本的了解,可以进一步进行数据分析和建模工作。

2.计算欺诈交易占数据集中交易总数的百分比

# 计算欺诈交易数量
fraud_count = creditcard_data[creditcard_data['Class'] == 1].shape[0]
# 计算总交易数量
total_count = creditcard_data.shape[0]
# 计算百分比
fraud_percentage = (fraud_count / total_count) * 100
# 打印结果
print(f'欺诈交易占总交易数的百分比: {fraud_percentage:.2f}%')

结果如下:
在这里插入图片描述

使用条件筛选creditcard_data[creditcard_data[‘Class’] == 1]获取所有标记为欺诈交易的数据,然后使用shape[0]计算行数(即欺诈交易的数量)。

欺诈案件总归占少数,隐藏在真实的交易中。
创建一个图表,将欺诈与非欺诈的数据点可视化

import matplotlib.pyplot as plt
import numpy as np

# prep_data(df)从数据集中提取特征和标签
def prep_data(df):
    X = df.iloc[:, 1:28]  #选择第1列到第28列的数据作为特征
    X = np.array(X).astype(float) #将数据框转换为numpy数组,并将数据类型转换为float(浮点数)
    y = df.iloc[:, 29] #选择第29列的数据作为标签(目标变量)(1表示欺诈,0表示正常)
    y = np.array(y).astype(float) #标签转换为numpy数组
    return X, y

def plot_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()
    return plt.show()

X, y = prep_data(creditcard_data)

plot_data(X, y)

结果如下:
在这里插入图片描述

欺诈性交易的比例非常低,类别不平衡

3. 类别不平衡对模型的影响

3.1 总体思路

数据集是信用卡交易记录,我们想通过这个数据找出哪些交易是欺诈行为,哪些是正常的交易。

我们希望建立一个聪明的模型,帮助我们准确地识别哪些交易是欺诈行为。

可以分为几个简单的步骤:

(1)数据的划分

首先,我们把数据分成两部分:一部分用于训练模型,另一部分用于测试模型。打个比方,用历年真题来学习,用今年的考试题来测试学习效果。

(2)训练模型

这里我们打算使用“逻辑回归”的数学方法来训练我们的模型。让这个模型会学到哪些交易看起来像是欺诈,哪些交易看起来是正常的。

(3)测试模型

训练好模型后,用测试数据来检查模型的表现。我们会得到一个结果表,显示模型预测的和实际的结果对比。比如,模型认为某些交易是欺诈,但实际上它们不是;或者模型认为某些交易是正常的,但实际上它们是欺诈。

(4)解决不平衡问题

我们的数据里,正常交易很多,欺诈交易很少。为了让模型更好地识别欺诈交易,我们使用了一种叫做SMOTE的方法。这个方法会“制造”一些假的欺诈交易,让数据看起来更平衡,就像我们在班级里增加一些假人,让男女比例更均匀。
也就是说用 SMOTE 来重新平衡数据,它不只是创建观察值的精确副本,而是使用欺诈交易的最近邻居的特征来创建新的、合成的样本,这些样本与少数人类别中的现有观察值相当相似

3.2 为什么要解决不平衡问题

在训练模型时,希望模型能更好地学习到如何识别每一类数据。

如果数据非常不平衡,比如正常交易很多,欺诈交易很少,模型会倾向于只学习正常交易,而忽略了欺诈交易。

打个比方,假设你在班级里玩一个游戏,老师给你看10张卡片,其中9张是苹果,1张是橙子。然后老师让你猜下一张卡片是什么。你很可能会猜是苹果,因为苹果的卡片太多了。如果这个时候老师给你多一些橙子的卡片,比如让你看到5张苹果和5张橙子,那么你在猜下一张卡片时,就会更认真地考虑两种可能性。

对于模型来说也是这样,如果我们的数据里正常交易很多,欺诈交易很少,模型在训练过程中会主要学习到正常交易的特征,而不会很好地学习到欺诈交易的特征。

结果就是模型会更倾向于预测所有的交易都是正常的,

解决方法——让数据平衡:

为了让模型更好地学习到两类交易的特征,我们可以使用一些技术手段,比如SMOTE。这种方法会“制造”一些假的欺诈交易,让数据看起来更平衡。

这样模型在训练过程中会看到更多的欺诈交易,更好地理解每一类数据的特征,从而更准确地识别出欺诈交易

这样,在预测时就会更准确地判断哪些交易是正常的,哪些是欺诈的。
就像你在玩卡片游戏时,看到的苹果和橙子数量差不多,你在猜下一张卡片时就会更准确一样。

4. 处理不平衡数据集

让我们把SMOTE应用于该信用卡数据,提供了更多的少数类别的观察结果
SMOTE首先识别数据集中属于少数类的样本。
对于每个少数类样本,SMOTE会在其最近邻样本中随机选择一个样本。
在这两个样本之间随机插值,生成一个新的合成样本。
通过上述步骤生成足够多的合成样本,使得少数类样本数量与多数类样本数量接近或相等。

from imblearn.over_sampling import SMOTE

# 实例化SMOTE对象
method = SMOTE()

# 对数据进行过采样
X_resampled, y_resampled = method.fit_resample(X, y)

# 可视化过采样后的数据
plot_data(X_resampled, y_resampled)

# 打印过采样前后的记录数量
print(f'原始数据集记录数量: {X.shape[0]}')
print(f'过采样后数据集记录数量: {X_resampled.shape[0]}')

# 打印过采样前后的类别分布
print(f'原始数据集类别分布:\n{pd.Series(y).value_counts()}')
print(f'过采样后数据集类别分布:\n{pd.Series(y_resampled).value_counts()}')

结果如下:
在这里插入图片描述
原始数据集有284807条记录,其中284315条是正常交易(类别0),492条是欺诈交易(类别1)。
过采样后数据集有568630条记录,其中正常交易仍然是284315条,但欺诈交易增加到了284315条,使得类别更加平衡。

为了更好地看到这种方法的结果,这里将其与原始数据进行比较:

def compare_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)
    return plt.show()

print(f'Original set:\n'
      f'{pd.Series(y).value_counts()}\n\n'
      f'SMOTE:\n'
      f'{pd.Series(y_resampled).value_counts()}\n')

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

结果如下:
在这里插入图片描述
原始数据集类别分布:
0.0 284315
1.0 492
Name: count, dtype: int64
过采样后数据集类别分布:
0.0 284315
1.0 284315
Name: count, dtype: int64
SMOTE方法平衡了数据,少数群体现在与多数群体的规模相等

5. 训练和评估模型

在平衡了数据集之后,下一步训练和评估机器学习模型,以确保模型能够更准确地识别少数类(这里是欺诈交易)
这里用两种方法作对比:制定规则来识别欺诈交易,用机器学习模型来识别欺诈交易

5.1 回到原始数据,制定规则

基于原始数据,制定一些规则来识别欺诈行为,
基于对数据的观察和分析,定义一些特定的阈值来检测异常交易
例如,可以根据特征的平均值和标准差来设置阈值。

计算特征均值:
使用creditcard_data.groupby(‘Class’).mean().round(3)[[‘V1’, ‘V3’]]来计算特征V1和V3在不同类别(正常交易和欺诈交易)中的平均值。

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

结果为:
在这里插入图片描述
从输出可以看到,正常交易(Class 0)和欺诈交易(Class 1)在特征V1和V3上的平均值有显著差异。
对于正常交易(Class 0),特征V1和V3的平均值分别是0.008和0.012。
对于欺诈交易(Class 1),特征V1和V3的平均值分别是-4.772和-7.033。
这表明,欺诈交易的这两个特征值明显低于正常交易。

例如,可以制定一个规则:
如果交易的V1值小于-3并且V3值小于-5,则认为该交易是欺诈行为。
这是因为在欺诈交易中,V1和V3的平均值都显著低于正常交易。
为了评估这种方法的性能,我们将把标记的欺诈案例与实际案例进行比较

5.1.1 代码

定义规则:如果交易的V1值小于-3并且V3值小于-5,则认为该交易是欺诈行为。
使用该规则标记数据集中每一条交易是否为欺诈。

import pandas as pd

# 读取数据集
creditcard_data = pd.read_csv('creditcard.csv', index_col=0)

# 计算特征均值
mean_values = creditcard_data.groupby('Class').mean().round(3)[['V1', 'V3']]
print(mean_values)

# 制定规则:V1 < -3 和 V3 < -5
def rule_based_detection(row):
    if row['V1'] < -3 and row['V3'] < -5:
        return 1  # 标记为欺诈
    else:
        return 0  # 标记为正常

# 应用规则
creditcard_data['Predicted_Class'] = creditcard_data.apply(rule_based_detection, axis=1)

# 计算混淆矩阵和分类报告
from sklearn.metrics import confusion_matrix, classification_report

y_true = creditcard_data['Class']
y_pred = creditcard_data['Predicted_Class']

print("Confusion Matrix:")
print(confusion_matrix(y_true, y_pred))
print("\nClassification Report:")
print(classification_report(y_true, y_pred))

运行结果为
在这里插入图片描述

5.1.2 结果分析

计算混淆矩阵和分类报告
计算实际标签(Class)和预测标签(Predicted_Class)之间的混淆矩阵和分类报告,评估规则的性能。

混淆矩阵

Confusion Matrix:
[[283089 1226]
[ 322 170]]
283089个正常交易被正确分类为正常交易(真阴性)。
1226个正常交易被错误分类为欺诈交易(假阳性)。
322个欺诈交易被错误分类为正常交易(假阴性)。
170个欺诈交易被正确分类为欺诈交易(真阳性)。

分类报告

Precision(精确率):
类0(正常交易):精确率是1.00,表示所有被预测为正常交易的样本中,实际是正常交易的比例是100%。
换句话说,模型对正常交易的预测非常准确,没有将正常交易误判为欺诈交易。
类1(欺诈交易):精确率是0.12,表示所有被预测为欺诈交易的样本中,实际是欺诈交易的比例是12%。
这意味着在所有被标记为欺诈交易的样本中,只有12%是真正的欺诈交易,正常交易很大可能被误识别为欺诈交易。

Recall(召回率):
类0(正常交易):召回率是1.00,表示所有实际为正常交易的样本中,正确被预测为正常交易的比例是100%。
模型能够识别出所有的正常交易,没有漏掉任何正常交易。
类1(欺诈交易):召回率是0.35,表示所有实际为欺诈交易的样本中,正确被预测为欺诈交易的比例是35%。
在所有实际的欺诈交易中,只有35%被模型正确识别为欺诈交易,其余65%被误识别为正常交易。也就是说,很多欺诈交易会被误识别为正常交易。

打个比方:
假设有100个样本,模型预测有20个是欺诈交易(类1),但实际上只有2个是欺诈交易,其余18个是正常交易。模型预测80个是正常交易(类0),其中实际有78个是正常交易,其余2个是欺诈交易。
精确率(类1):
预测为欺诈的20个样本中,只有2个是实际欺诈,所以精确率 = 2/20 = 0.10。
召回率(类1):
实际为欺诈的4个样本中,只有2个被正确识别,所以召回率 = 2/4 = 0.50。

F1-score:
类0(正常交易):F1-score是1.00,是精确率和召回率的调和平均数。
类1(欺诈交易):F1-score是0.18,表示模型对欺诈交易的分类效果较差。

F1-score 同时考虑了精确率和召回率两个方面,是精确率(Precision)和召回率(Recall)的调和平均数,用来衡量模型在分类任务中的性能。F1-score 适用于不平衡数据集。
F1-score = 2 × Precision × Recall Precision + Recall \text{F1-score} = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}} F1-score=2×Precision+RecallPrecision×Recall
类0(正常交易):
精确率(Precision) 和 召回率(Recall) 都是1.00。 因此,F1-score 也是1.00。
这表明模型对正常交易的分类效果非常好,能够准确且全面地识别正常交易,没有误分类和漏分类的情况。

类1(欺诈交易):
精确率(Precision) 是0.12,表示所有被预测为欺诈交易的样本中,实际是欺诈交易的比例。
召回率(Recall) 是0.35,表示所有实际为欺诈交易的样本中,正确被预测为欺诈交易的比例。
F1-score 为 0.18
F1-score = 2 × 0.12 × 0.35 0.12 + 0.35 = 2 × 0.042 0.47 ≈ 0.18 \text{F1-score} = 2 \times \frac{0.12 \times 0.35}{0.12 + 0.35} = 2 \times \frac{0.042}{0.47} \approx 0.18 F1-score=2×0.12+0.350.12×0.35=2×0.470.0420.18
表示模型对欺诈交易的分类效果较差。误报率较高(精确率低),漏报率也较高(召回率低)

Accuracy(准确率), 正确分类的样本数占总样本数的比例
Accuracy = TP + TN TP + TN + FP + FN \text{Accuracy} = \frac{\text{TP} + \text{TN}}{\text{TP} + \text{TN} + \text{FP} + \text{FN}} Accuracy=TP+TN+FP+FNTP+TN
混淆矩阵:
TN(True Negative):283089 - 正常交易被正确分类为正常交易
FP(False Positive):1226 - 正常交易被错误分类为欺诈交易
FN(False Negative):322 - 欺诈交易被错误分类为正常交易
TP(True Positive):170 - 欺诈交易被正确分类为欺诈交易
模型在所有样本中有99%的样本被正确分类,很高的准确率,但在不平衡数据集中,准确率并不能全面反映模型的性能,特别是对少数类(如欺诈交易)的识别能力。

支持度(Support)分类的样本数量,正常交易远多于欺诈交易,数据集极度不平衡
类0(正常交易)的样本数是284315。
类1(欺诈交易)的样本数是492。
高准确率主要是由于模型对正常交易的高识别率(几乎所有正常交易都被正确分类)
然而,模型对欺诈交易的识别效果较差,这可以从较低的类1(欺诈交易)的精确率、召回率和F1-score中看出。

Macro avg,宏平均,不同类别的指标的简单平均值。
精确率、召回率和F1-score分别是0.56、0.67和0.59。
简单平均,它反映了每个类别的指标对等的重要性。对于不平衡的数据集,少数类(如欺诈交易)的表现对这个值有较大影响

Weighted avg,加权平均,考虑了类别的样本数量,占主导地位的多数类(如正常交易)的指标。因此,即使欺诈交易的表现较差,由于正常交易占多数,整体的加权平均值仍然很高。
精确率、召回率和F1-score分别是1.00、0.99和1.00

结论

基于原始数据,制定一些规则来识别欺诈行为,检测效果不佳。

5.2 逻辑回归模型(未使用SMOTE)和逻辑回归模型(使用SMOTE)

代码及结果
import numpy as np
import pandas as pd
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.pipeline import Pipeline

# 读取数据集
creditcard_data = pd.read_csv('creditcard.csv', index_col=0)
print(f"Original dataset size: {creditcard_data.shape[0]}")

# 平衡数据集
X, y = creditcard_data.iloc[:, 1:28], creditcard_data.iloc[:, 29]
smote = SMOTE()
X_resampled, y_resampled = smote.fit_resample(X, y)
print(f"Resampled dataset size: {X_resampled.shape[0]}")

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
print(f"Training set size: {X_train.shape[0]}")
print(f"Test set size: {X_test.shape[0]}")

# 训练逻辑回归模型并评估
lr = LogisticRegression()
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
print("Logistic Regression (without SMOTE):")
print(pd.crosstab(y_test, predictions, rownames=['Actual Fraud'], colnames=['Flagged Fraud']))
print(confusion_matrix(y_test, predictions))
print(classification_report(y_test, predictions))

# 结合SMOTE和逻辑回归
pipeline = Pipeline([('SMOTE', smote), ('Logistic Regression', lr)])
pipeline.fit(X_train, y_train)
predictions = pipeline.predict(X_test)
print("Logistic Regression with SMOTE:")
print(pd.crosstab(y_test, predictions, rownames=['Actual Fraud'], colnames=['Flagged Fraud']))
print(confusion_matrix(y_test, predictions))
print(classification_report(y_test, predictions))

结果如下:
在这里插入图片描述
数据集划分:
原始数据集被划分为训练集和测试集,其中 X_train 和 y_train 用于训练模型,X_test 和 y_test 用于评估模型。
train_test_split(X, y, test_size=0.3, random_state=0) 将 70% 的数据用作训练集,30% 的数据用作测试集。

模型训练和评估:
训练逻辑回归模型时,使用的是 X_train 和 y_train。
在测试集上进行预测,并生成混淆矩阵和分类报告时,使用的是 X_test 和 y_test。

测试集中,正常交易的样本数为 85296,欺诈交易的样本数为 147。
分类报告反映的是模型在测试集上的性能评估结果

混淆矩阵

Logistic Regression(未使用SMOTE)

Logistic Regression (without SMOTE):
Flagged Fraud      0     1
Actual Fraud              
0              85284    12
1                 58    89
[[85284    12]
 [   58    89]]

85284:正常交易正确分类(真负例)
12:正常交易误分类为欺诈交易(假阳性)
58:欺诈交易误分类为正常交易(假阴性)
89:欺诈交易正确分类(真阳性)

Logistic Regression with SMOTE(使用SMOTE)

Logistic Regression with SMOTE:
Flagged Fraud      0     1
Actual Fraud              
0              83101  2195
1                 12    135
[[83101  2195]
 [   12   135]]

83101:正常交易正确分类(真负例)
2195:正常交易误分类为欺诈交易(假阳性)
12:欺诈交易误分类为正常交易(假阴性)
135:欺诈交易正确分类(真阳性)

分类报告

Logistic Regression(未使用SMOTE)

              precision    recall  f1-score   support

           0       1.00      1.00      1.00     85296
           1       0.88      0.61      0.72       147

    accuracy                           1.00     85443
   macro avg       0.94      0.80      0.86     85443
weighted avg       1.00      1.00      1.00     85443

正常交易(类0):精确率、召回率和F1-score都为1.00。
欺诈交易(类1):精确率为0.88,召回率为0.61,F1-score为0.72,模型在识别欺诈交易时漏报较多,但误报较少。

Logistic Regression(使用SMOTE)

              precision    recall  f1-score   support

           0       1.00      0.97      0.99     85296
           1       0.06      0.92      0.11       147

    accuracy                           0.97     85443
   macro avg       0.53      0.95      0.55     85443
weighted avg       1.00      0.97      0.99     85443

正常交易(类0):精确率仍然为1.00,但召回率下降到0.97,F1-score为0.99。
欺诈交易(类1):精确率下降到0.06,但召回率显著提高到0.92,F1-score为0.11。能识别大部分欺诈交易,但误报较多。

未使用SMOTE:模型对正常交易的识别效果非常好,但召回率较低,对欺诈交易的识别较差。
使用SMOTE:模型对欺诈交易的识别效果显著提高,召回率达到0.92,但精确率大幅下降,误报增多。

6. 进一步

可以看到,逻辑回归模型在处理欺诈检测问题上,比简单的阈值设定规则(例如V1 < -3 和 V3 < -5)能更好地识别欺诈交易。

为了提高逻辑回归模型的准确性,可以调整一些算法参数(如正则化参数),也可以考虑使用k-fold交叉验证而不是简单地将数据集分成训练集和测试集,交叉验证通过多次分割和训练数据集,减少了因数据分割随机性带来的误差,可以更好地评估模型的性能并选择最佳的模型参数,提高模型的稳定性和泛化能力。

也可以尝试不同的SMOTE参数,找到平衡精确率和召回率的最佳参数,如 sampling_strategy 和 k_neighbors,以找到最佳的参数组合,当欺诈记录在数据集中非常分散时,SMOTE可能会引入偏见,因为生成的合成样本可能不代表实际的欺诈模式,所以使用SMOTE会引入偏见问题。

还可以尝试一些其他的机器学习算法(如如随机森林、XGBoost),找到平衡精确率和召回率的最佳方案,从而在实际应用中更有效地识别欺诈交易

7. 随机森林模型

混淆矩阵和分类报告,显示该模型在正常交易数量远远多于欺诈交易的情况下,欺诈检测表现是比较理想的

import pandas as pd
import numpy as np
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score, roc_curve
from imblearn.pipeline import Pipeline
import matplotlib.pyplot as plt
import joblib

# 数据预处理函数
def prep_data(df):
    X = df.iloc[:, 1:28]
    y = df.iloc[:, 29]
    return np.array(X).astype(float), np.array(y).astype(float)

# 读取数据集
creditcard_data = pd.read_csv('creditcard.csv', index_col=0)

# 数据预处理
X, y = prep_data(creditcard_data)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建并训练随机森林模型的管道
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('smote', SMOTE()),
    ('randomforestclassifier', RandomForestClassifier(random_state=42))
])

# 训练模型
pipeline.fit(X_train, y_train)

# 预测测试集
y_pred = pipeline.predict(X_test)

# 打印混淆矩阵和分类报告
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
print("\nClassification Report:")
print(classification_report(y_test, y_pred))

# 保存模型
joblib.dump(pipeline, 'random_forest_fraud_model.pkl')
print("Model saved as random_forest_fraud_model.pkl")

结果如下
在这里插入图片描述

8. 模型应用

关于模型的应用,需要结合实际情况优化方案,粗略的思路,例如:
目前看起来有了一个好用的模型,以后有新的交易数据进来,先把这些数据按照之前训练集的标准整理好,数据格式和特征都和训练时一致,加载模型,把整理好的数据交给模型,让它来判断哪些交易是正常的,哪些可能是欺诈的。

模型会给出一个判断结果,比如:
1 表示欺诈交易
0 表示正常交易
以下是未经运行的示例

误报处理

对于模型标记为欺诈的交易(但可能是正常交易),引入人工审核,比如,设立团队对这些交易进行复查,处理被误报的正常交易

漏报处理

对于模型没有标记为欺诈的交易(但实际上可能是欺诈交易),需要降低漏报率
例如,提高模型阈值
让模型输出每笔交易是欺诈的概率,根据业务需求调整判断标准(阈值),比如当概率大于0.5时标记为欺诈。

再如,组合多个模型提高判断的准确性
使用多个不同的模型,并取大家的综合结果
也可以进一步更新和优化训练模型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/802563.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

django报错(二):NotSupportedError:MySQL 8 or later is required (found 5.7.43)

执行python manage.py runserver命令时报版本不支持错误&#xff0c;显示“MySQL 8 or later is required (found 5.7.43)”。如图&#xff1a; 即要MySQL 8或更高版本。但是企业大所数用的还是mysql5.7相关版本。因为5.7之后的8.x版本是付费版本&#xff0c;贸然更新数据库肯定…

python自动化之用flask校验接口token(把token作为参数)

用到的库&#xff1a;flask 实现效果: 写一个接口&#xff0c;需要token正确才能登录 代码&#xff1a; # 导包 from flask import Flask,request,jsonify,json # 创建一个服务 appFlask(__name__) # post请求&#xff0c;路径&#xff1a;/query app.route(/query, met…

框架设计MVC

重点&#xff1a; 1.用户通过界面操作&#xff0c;传输到control&#xff0c;control可以直接去处理View&#xff0c;或者通过模型处理业务逻辑&#xff0c;然后将数据传输给view。 2.control包含了model和view成员。 链接&#xff1a; MVC框架详解_mvc架构-CSDN博客 MVC架…

【香橙派 Orange pi AIpro】| 搭建部署基于Yolov5的车牌识别系统

【香橙派 Orange pi AIpro】| 搭建部署基于Yolov5的车牌识别系统 一、香橙派 Orange pi AIpro 开发板介绍及实物开箱1.1 开发板介绍1.2 产品详情图1.3 开箱实物 二、开发部署预先准备2.1 镜像介绍与烧录2.2 启动开发板2.3 连接开发板 三、基于Yolov5的车牌识别系统3.1 项目介绍…

前端pc和小程序接入快递100(跳转方式和api方式)====实时查询接口

文章目录 跳转方式微信小程序&#xff08;我以uniapp为例&#xff09;pc api接入说明关于签名计算成功示例 跳转方式 没有任何开发成本&#xff0c;直接一键接入 可以直接看官方文档 https://www.kuaidi100.com/openapi/api_wxmp.shtml 微信小程序&#xff08;我以uniapp为例…

知识图谱与 LLM:微调与检索增强生成

Midjourney 的知识图谱聊天机器人的想法。 大型语言模型 (LLM) 的第一波炒作来自 ChatGPT 和类似的基于网络的聊天机器人&#xff0c;这些模型在理解和生成文本方面非常出色&#xff0c;这让人们&#xff08;包括我自己&#xff09;感到震惊。 我们中的许多人登录并测试了它写…

大数据信用查询有哪些问题值得注意呢?

随着大数据技术的不断发展&#xff0c;大数据信用报告成为一种新型的信用风险检测工具&#xff0c;被很多的银行和机构广泛用于信用风险评估&#xff0c;那大数据信用查询有哪些问题值得注意呢?本文就带大家一起去了解一下&#xff0c;希望对你有一定的帮助。 大数据信用查询这…

数据结构——单链表详解(超详细)(2)

前言&#xff1a; 上一篇文章小编简单的介绍了单链表的概念和一些函数的实现&#xff0c;不过为了保证文章的简洁&#xff0c;小编把它分成了两篇来写&#xff0c;这一篇小编紧接上一篇文章继续写单链表函数功能的实现&#xff1a; 目录&#xff1a; 1.单链表剩余函数的编写 1.…

使用Windows Linux 子系统安装 Tensorflow,并使用GPU环境

在Microsoft Store商店安装Ubuntu 20.04 使用 nvidia-smi 命令查看GPU信息&#xff0c;查看支持的CUDA版本&#xff0c;这里最高支持11.7 安装cuda工具集 进入官网&#xff1a;CUDA Toolkit Archive | NVIDIA Developer&#xff0c;现在对应版本&#xff0c;点击 配置平台&…

【Django+Vue3 线上教育平台项目实战】登录功能模块之短信登录与钉钉三方登录

文章目录 前言一、几个关键概念1.HTTP无状态性2.Session机制3.Token认证4.JWT 二、通过手机号验证码登录1.前端短信登录界面2.发送短信接口与短信登录接口3.Vue 设置interceptors拦截器4. 服务端验证采用自定义中间件方式实现5. 操作流程及效果图如下&#xff1a; 三、通过第三…

对某根域的一次渗透测试

前言 两个月之前的一个渗透测试项目是基于某网站根域进行渗透测试&#xff0c;发现该项目其实挺好搞的&#xff0c;就纯粹的没有任何防御措施与安全意识所以该项目完成的挺快&#xff0c;但是并没有完成的很好&#xff0c;因为有好几处文件上传没有绕过&#xff08;虽然从一个…

【Java】数据类型及类型转换

数据类型 Java语言的数据类型分为两大类&#xff1a; 基础数据类型引用数据类型 基础数据类型 基础数据类型包括以下8种&#xff1a; 类型名称关键字占用内存取值范围区间描述字节型byte1 字节-128~127-27~27-1短整型short2 字节-32768~32767-215~215-1整型int4 字节-2147…

nftables(7)集合(SETS)

简介 在nftables中&#xff0c;集合&#xff08;sets&#xff09;是一个非常有用的特性&#xff0c;它允许你以集合的形式管理IP地址、端口号等网络元素&#xff0c;从而简化规则的配置和管理。 nftables提供了两种类型的集合&#xff1a;匿名集合和命名集合。 匿名集合&…

高职院校人工智能人才培养成果导向系统构建、实施要点与评量方法

一、引言 近年来&#xff0c;人工智能技术在全球范围内迅速发展&#xff0c;对各行各业产生了深远的影响。高职院校作为培养高技能人才的重要基地&#xff0c;肩负着培养人工智能领域专业人才的重任。为了适应社会对人工智能人才的需求&#xff0c;高职院校需要构建一套科学、…

大模型产品琳琅满目,企业应该如何选择?

AI 和大模型方兴未艾&#xff0c;我们每天都在看到和尝试不同版本、不同品牌的大模型产品&#xff0c;它们的能力各不相同。无论是个人还是企业&#xff0c;都在思考如何尽早地参与进来到大模型的浪潮当中来。 目前&#xff0c;一些先锋企业已经将 AI 和大模型融入到他们的日常…

C#学习

C#学习 1.B站丑萌气质狗C#的循环-判断泛型错误处理面向对象static的使用定义showInfo类和Hero类 在这里插入图片描述 然后在该解决方案add新建一个类库&#xff0c;点击rebuild&#xff0c;会在bin文件夹下生成.dll文件 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direc…

无人机之图传距离的决定因素

一、发射功率&#xff1a;图传设备的发射功率越大&#xff0c;信号能够传播的距离就越远 二、工作频段&#xff1a;不同频段具有不同的传播特性&#xff0c;一些频段在相同条件下可能具有更远的传输距离。 三、天线性能&#xff1a;优质的天线可以增强信号的发送和接收能力&a…

php相关

php相关 ​ 借鉴了小迪安全以及各位大佬的博客&#xff0c;如果一切顺利&#xff0c;会不定期更新。 如果感觉不妥&#xff0c;可以私信删除。 默认有php基础。 文章目录 php相关1. php 缺陷函数1. 与2. MD53. intval()4. preg_match() 2. php特性1. php字符串解析特性2. 杂…

jdk22+maven环境配置教程+idea的maven环境配置(Windows系统)

前言 jdk是Java开发必要的编程环境&#xff0c;idea是常用的Java开发工具&#xff0c;这里着重解释一下maven。 maven就是我们经常看见的pom.xml文件&#xff0c;maven有以下三点功能&#xff1a; 1.项目构建&#xff08;可以帮助我们更快速的打包、构建项目&#xff09; 2.依…

<数据集>钢铁缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1800张 标注数量(xml文件个数)&#xff1a;1800 标注数量(txt文件个数)&#xff1a;1800 标注类别数&#xff1a;6 标注类别名称&#xff1a;[crazing, patches, inclusion, pitted_surface, rolled-in_scale, scr…