常见的数据分析用例 —— 信用卡交易欺诈检测
文章目录
- 引言
- 数据集
- 分析
- 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 pdcreditcard_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 float641 V2 284807 non-null float642 V3 284807 non-null float643 V4 284807 non-null float644 V5 284807 non-null float645 V6 284807 non-null float646 V7 284807 non-null float647 V8 284807 non-null float648 V9 284807 non-null float649 V10 284807 non-null float6410 V11 284807 non-null float6411 V12 284807 non-null float6412 V13 284807 non-null float6413 V14 284807 non-null float6414 V15 284807 non-null float6415 V16 284807 non-null float6416 V17 284807 non-null float6417 V18 284807 non-null float6418 V19 284807 non-null float6419 V20 284807 non-null float6420 V21 284807 non-null float6421 V22 284807 non-null float6422 V23 284807 non-null float6423 V24 284807 non-null float6424 V25 284807 non-null float6425 V26 284807 non-null float6426 V27 284807 non-null float6427 V28 284807 non-null float6428 Amount 284807 non-null float6429 Class 284807 non-null int64
dtypes: float64(29), int64(1)
memory usage: 67.4 MB
NoneV1 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, ydef 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_reporty_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.042≈0.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 support0 1.00 1.00 1.00 852961 0.88 0.61 0.72 147accuracy 1.00 85443macro 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 support0 1.00 0.97 0.99 852961 0.06 0.92 0.11 147accuracy 0.97 85443macro 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时标记为欺诈。
再如,组合多个模型提高判断的准确性
使用多个不同的模型,并取大家的综合结果
也可以进一步更新和优化训练模型
相关文章:
常见的数据分析用例 —— 信用卡交易欺诈检测
文章目录 引言数据集分析1. 读入数据并快速浏览2.计算欺诈交易占数据集中交易总数的百分比3. 类别不平衡对模型的影响3.1 总体思路(1)数据的划分(2)训练模型(3)测试模型(4)解决不平衡…...
IP地址:由电脑还是网线决定?
IP地址:由电脑还是网线决定? 在互联网时代,IP地址是我们进行网络通信的基础。然而,对于IP地址究竟是由电脑决定还是由网线决定的问题,不少人可能存在疑惑。本文将从IP地址的定义、分配方式以及影响因素等方面进行探讨…...
如何定位及优化SQL语句的性能
在数据库管理和优化中,定位并解决SQL语句的性能问题是至关重要的。MySQL通过EXPLAIN命令提供了强大的工具来查看SQL语句的执行计划,这是定位性能瓶颈和优化SQL语句的首要步骤。以下是如何利用执行计划来定位及优化SQL语句性能问题的详细指南。 一、使用…...
SentenceTransformers (SBERT)
文章目录 一、关于 SBERT特点预训练模型应用实例 二、安装开发设置 三、入门使用四、训练五、Cross Encoder 一、关于 SBERT 官方文档:https://www.sbert.net/github : https://github.com/UKPLab/sentence-transformerspaper : Sentence-BERT: Sentence Embedding…...
第三届智能机械与人机交互技术学术会议(IHCIT 2024)
【北航主办丨本届SPIE独立出版丨已确认ISSN号】 第三届智能机械与人机交互技术学术会议(IHCIT 2024) 2024 3rd International Conference on Intelligent Mechanical and Human-Computer Interaction Technology 2024年7月27日----中国杭州࿰…...
图的访问(C++)
题目描述 给出 N 个点,M 条边的有向图,对于每个点 v,求 A(v) 表示从点 v 出发,能到达的编号最大的点。 输入格式 第 1 行 2 个整数 N,M,表示点数和边数。 接下来 M 行,每行 2 个整数 Ui,Vi,表…...
LeetCode做题记录(第二天)169. 多数元素
题目:169. 多数元素 标签:数组 哈希表 分治 计数 排序 题目信息: 思路一: 在题目中出现了计数,那我们就可以直接考虑考虑使用哈希表 unordered_map 即遍历的时候记录每个数的出现次数,当出现次数大于n/…...
Adobe XD中文设置指南:专业设计师的现场解答
Adobe XD是世界领先的在线合作UI设计工具。它摆脱了Sketch、Figma等传统设计软件对设备的依赖,使设计师可以随时随地使用任何设备打开网页浏览器,轻松实现跨平台、跨时空的设计合作。然后,为了提高国内设计师的使用体验,Adobe XD如…...
CentOS 7 安装Jenkins2.346.1(war方式安装)
既然想要安装Jenkins,肯定是先要从官网解读所需环境配置信息,如需了解更多自行查阅 https://www.jenkins.io/doc/book/installing/linux/ JDK17,Maven3.9 安装 先从官网分别下载JDK17与Maven3.9 下载好之后上传至服务器、并解压:…...
使用Java -jar运行就jar包时报异常:org.yaml.snakeyaml.error.YAMLException异常
Java运行就 .jar包时出现的 YAMLException 异常 我在本地环境测试时,使用 java -jar 命令运行 Java 可执行 .jar 包时,遇到了 org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length 1 异常;这…...
golang实现的ab测试http代理工具
压测工具ab不能统计http请求的错误情况,包括http状态码错误和响应正文的错误关键字。 所以加层代理用于统计http错误情况,重在统计错误情况,而不是代理的性能,主要用于功能接口的测试,比如测试一下请求多少次接口会返…...
Maven学习——Maven的下载、安装与配置(详细攻略!)
目录 前言 1.下载与安装 2.配置Maven的环境变量 3.配置Maven的本地仓库 4. 配置Maven的镜像远程仓库 前言 我在之前写了一篇博客,是介绍Maven的基本概念和下载安装,但是由于篇幅过长,Maven的下载与安装写的并不详细🐶&#x…...
C#知识|账号管理系统-修改账号按钮功能的实现
哈喽,你好啊,我是雷工! 前边学习了通过选择条件查询账号的功能: 《提交查询按钮事件的编写》 本节继续学习练习C#,今天练习修改账号的功能实现。 以下为学习笔记。 01 实现功能 ①:从查询到的账号中,选择某一账号,然后点击【修改账号】按钮,将选中的信息获取显示到…...
bug等级和优先级
一、bug的等级 1、致命 这类bug是最严重的,通常导致系统无法运行、主要功能失效或严重资源不足。举例包括软件在安装过程中崩溃,导致无法完成安装;登录功能失效,用户无法验证身份进入系统;主要功能模块(如…...
记录|C# winform布局学习
目录 前言一、自适应布局Step1. 添加AutoAdaptWindowsSize类Step2. Form中引用Step3. 创建SizeChanged事件函数Step4. 在Fram.Disiger中添加 更新时间 前言 参考视频: C#5分钟winform快速自适应布局 参考文章: 其他参考: 写这篇文章ÿ…...
C/C++ json库
文章目录 一、介绍1.1 json 介绍 二、C/C json 库选型2.1 选型范围2.2 jsoncpp2.2.2 jsoncpp 编译和交叉编译 2.3 rapidjson2.4 nlohmann/json2.5 sonic-cpp 五、常见问题5.1 jsoncpp 中关于浮点数的控制和中文显示问题5.2 jsoncpp序列化double类型时精度损失问题的解决办法 一…...
C++案例四:简易记事本程序
文章目录 程序介绍代码说明包含必要的头文件主函数定义变量定义主循环显示菜单和读取选择处理用户选择程序介绍 编写一个简单的记事本程序,可以帮助用户添加和查看笔记。这个案例可以练习C++中的输入输出、向量(std::vector)、字符串处理(std::string)、以及简单的控制结…...
【VUE学习】day03-过滤器filter
VUE学习第三天 过滤器filter全局过滤器私有过滤器 过滤器filter 作用:常见的文本格式化使用场景:插值表达式、v-bind用法:{{msg | filterName}} ; v-bind:属性‘msg | filterName’ msg:需要格式化的文本信息(管道符前面的数据&a…...
技术成神之路:设计模式(八)责任链模式
介绍 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象依次处理请求,避免请求的发送者和接收者之间的显式耦合。该模式通过将多个可能处理请求的对象连接成一条链,并沿着这条链传递请求…...
【Zynq UltraScale+ RFSoC】~~~
Zynq UltraScale RFSoC 系列为 5G 无线和射频级模拟应用引入了颠覆性的集成和架构突破,可直接支持整个 5G sub-6GHz 频段。这个创新系列现已开始批量生产。此设计演示展示了多通道(8T8R 或 16T16R)Zynq UltraScale RFSoC 评估工具工具工具&am…...
STM32之八:IIC通信协议
目录 1. IIC协议简介 1.1 主从模式 1.2 2根通信线 2. IIC协议时序 2.1 起始条件和终止条件 2.2 应答信号 2.3 发送一个字节 2.4 接收一个字节 3. IIC读写操作 3.1 写操作 3.2 读操作 1. IIC协议简介 IIC协议是一个半双工、同步、一主多从、多主多从的串行通用数据总…...
mysql的数据往hive进行上报时怎么保证数据的准确性和一致性
在将MySQL的数据往Hive进行上报时,确保数据的准确性和一致性可以通过下面一系列步骤来实现 一、准备工作 环境配置: 确保MySQL和Hive环境已经安装并配置好,且都处于可运行状态。检查Hadoop集群(Hive通常运行在Hadoop之上&#x…...
问题:4、商业保险与政策性保险的主要不同之处是:经营主体不同、经营目标不同、承保机制不同。 #学习方法#其他#学习方法
问题:4、商业保险与政策性保险的主要不同之处是:经营主体不同、经营目标不同、承保机制不同。 参考答案如图所示...
Getx学习笔记之中间件鉴权
目录 前言 一、实现步骤 1.添加依赖 2.创建鉴权中间件 3.定义路由 4.设置初始路由 5.模拟登陆状态 二、Getx鉴权步骤总结 三、本文demo示例 四、参考文章 前言 在 Flutter 中,使用 GetX 可以很方便地实现中间件鉴权(Authentication)…...
介绍 Elasticsearch 中的 Learning to Tank - 学习排名
作者:来自 Elastic Aurlien Foucret 从 Elasticsearch 8.13 开始,我们提供了原生集成到 Elasticsearch 中的学习排名 (learning to rank - LTR) 实现。LTR 使用经过训练的机器学习 (ML) 模型为你的搜索引擎构建排名功能。通常,该模型用作第二…...
2024年计算机软考中级【硬件工程师】面试题目汇总(附答案)
硬件工程师面试题汇总分析 1、解释一下同步电路和异步电路 解题思路 同步电路和异步电路是指同步时序电路和异步时序电路。由于存储电路中触发器的动作特点不同,因此可以把时序电路分为同步时序电路和异步时序电路两种。同步时序电路所有的触发器状态的变化都是在同…...
ThinkPad改安装Windows7系统的操作步骤
ThinkPad:改安装Windows7系统的操作步骤 一、BIOS设置 1、先重新启动计算机,并按下笔记本键盘上“F1”键进入笔记本的BIOS设置界面。 2、进入BIOS设置界面后,按下键盘上“→”键将菜单移动至“Restart“项目,按下键盘上“↓”按键…...
微软Edge浏览器全解析教程
微软Edge浏览器全解析教程 微软Edge浏览器,作为微软公司精心打造的一款现代化网页浏览器,自其首次发布以来,凭借其卓越的性能、出色的用户体验和不断迭代的功能,赢得了广大用户的青睐。本文将全面解析微软Edge浏览器的各个方面&a…...
【过题记录】7.20
前两题一直在打模拟赛,有点忙,就没更 Red Playing Cards 算法:动态规划 其实这就是一个线段覆盖问题,只不过大线段能够包含小线段。 这就启发我们,对于每个大线段分别跑一个dp,合并在他内部的小线段。而后…...
Linux系统学习日记——vim操作手册
Vim编辑器是linux下的一个命令行编辑器,类似于我们windows下的记事本。 目录 打开文件 编辑 保存退出 打开文件 打开 hello.c不存在也可以打开,保存时vim会自动创建。 效果 Vim打开时,处于命令模式,即执行命令的模式&#x…...
建设网站的相关费用/百度打广告收费表
dd单链据结构定义 typedef struct LNode {int data;struct LNode *next; }LNode,*LinkList; 单链表的初始化 void InitList(LinkList&L) {Lnew LNode;;L->nextNULL; } 单链表的插入 1.把结点插入链表最后一位,如果想插入特定位置只需要改变while条件 v…...
赶集招聘网/seo搜索引擎优化技术
冒泡排序对于时间复杂度来说是很大的,“桶排序”对于空间复杂度来说是很大的。 问题引入 我们现在要对6 1 2 7 9 3 4 5 10 8进行排序。首先,我们找到一个参考数,比如第一个位置的6吧!我们接下来就是把大于参考数的元素放到参考数的…...
网站软文写作要求/淘宝关键词搜索量查询
2019独角兽企业重金招聘Python工程师标准>>> 1.介绍 是一款桌面录像很好的软件 下载地址:http://yunpan.cn/cZE53uszCyvhb 访问密码 cb90 2.安装 2.1.点击屏幕录像专家.exe 2.2.按照说明点击下一步,其中遇到这个界面注意按照勾选 2.3.…...
怎做不下网站刷枪/网络销售怎么才能找到客户
具体的报错信息:ArgumentException: Getting control 0s position in a group with only 0 controls when doing Repaint A OnGUI在每次绘制时会调用2次,第1次计算所有控件的位置,所有EdtorGUILayout控件方法返回的Rect均为0;第2次根据位置来…...
教做幼儿菜谱菜的网站/成都搜索优化排名公司
1 三次握手 TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP 协议提供可靠的连接服务,连接是通过三次握手🤝进行初始化的。三次握手🤝的目的是同步连…...
网站开发合同范本/谷歌浏览器下载电脑版
在一个服务内的业务处理通常需要不同类的共同协作来完成,比如controller接收请求,校验参数,然后调用service类的业务处理方法,而service又需要调用持久层的方法来读取和写入数据,为了在日志中,将各个部分的…...