6. 结果分析与解读

在本部分,我们将详细解读模型的评估结果,分析欺诈交易检测的有效性,并提供对业务的指导性见解。

6.1 评估结果回顾

在第 5 部分,我们训练了 XGBoost 模型,并使用** 随机搜索(RandomizedSearchCV)进行了超参数优化。最终,我们评估了优化前后的模型性能,并使用 混淆矩阵、ROC 曲线** 等工具进行可视化分析。

优化前后模型的主要评估指标如下:

图片[1]-6. 结果分析与解读-大赛人网

其中:

  • 精确率(Precision) 提高,意味着误报(假阳性)减少,减少了对正常用户的干扰。
  • 召回率(Recall) 提高,意味着检测出的欺诈交易数量增加,减少了潜在的损失。
  • F1-score 提高,表明模型在精准度和召回率之间找到了更好的平衡。

6.2 ROC 曲线分析

在 ROC 曲线分析中,我们计算了 AUC(曲线下面积):

AUC = 0.98

  • AUC 接近 1,说明模型可以很好地区分正常交易与欺诈交易。
  • 这意味着模型可以在不同的阈值下,保持较高的检测能力,同时避免误报过多。

指导性意义:

  • AUC 0.98 表明模型的整体性能优异,可以在不同应用场景中灵活调整决策阈值。
  • 在 高风险业务(如大额交易、国际支付)中,可以降低阈值,提高召回率,避免漏掉欺诈交易。
  • 在 低风险业务(如小额消费)中,可以提高阈值,减少误报,提高用户体验。

6.3 特征重要性分析

我们使用 XGBoost 提供的特征重要性分析,找出最具影响力的特征:

# 提取特征重要性
importance = best_model.feature_importances_

# 可视化特征重要性
plt.figure(figsize=(12, 6))
sns.barplot(x=X_train.columns, y=importance, palette="viridis")
plt.xticks(rotation=90)
plt.xlabel("Features")
plt.ylabel("Importance Score")
plt.title("Feature Importance in XGBoost")
plt.show()

最重要的特征:

  1. V17、V12、V14:与欺诈交易高度相关。
  2. V10、V4:在欺诈交易中有明显异常。
  3. 交易金额(Amount):虽然不是最重要的,但仍有一定贡献。

指导性意义:

  • 监控 V17、V12、V14 这几个关键变量,可以提升欺诈检测的准确性。
  • 结合交易金额和异常特征,可以对大额交易进行更严格的审核。
  • 针对特征进行进一步分析,可以尝试结合用户行为数据,提升检测能力。

6.4 误分类分析

我们分析了 误分类的欺诈交易 和误分类的正常交易,找出潜在改进点。

(1)误分类的欺诈交易

false_negatives = X_test[(y_test == 1) & (y_pred_best == 0)]
print("误分类的欺诈交易数量:", false_negatives.shape[0])
  • 这些交易可能是 新型欺诈模式,不符合历史欺诈交易的特征。
  • 可能涉及 复杂的欺诈手段(如分布式欺诈、社交工程欺诈)。

改进方向:

  • 结合 时间序列分析,看欺诈行为是否随时间变化。
  • 结合 用户行为特征,例如设备信息、交易频率等。

(2)误分类的正常交易

false_positives = X_test[(y_test == 0) & (y_pred_best == 1)]
print("误分类的正常交易数量:", false_positives.shape[0])
  • 误报的交易 可能是高额交易,但实际上是合法的。
  • 误报 可能影响正常用户体验,导致投诉。

改进方向:

  • 增加用户身份验证步骤,如短信验证码、设备指纹等,以减少正常用户的困扰。
  • 对高额交易提供风险评分,根据用户历史行为调整风险判断。

6.5 业务指导

根据以上分析,我们可以给出以下业务指导建议:

  1. 动态调整模型阈值
    • 对 高风险交易(大额、异常地点)降低阈值,提高召回率。
    • 对 普通交易(低额、常见地点)提高阈值,减少误报。
  2. 结合时间序列分析
    • 检查某些特定时间段(如深夜)是否更容易发生欺诈交易。
    • 监测用户交易频率,是否存在 短时间内大量交易 的异常行为。
  3. 多维度用户身份验证
    • 在高风险交易中 增加身份验证(如短信验证、人脸识别)。
    • 使用 历史行为模式,建立个性化风险评分,减少误报。
  4. 结合更多特征
    • 现有数据仅包含 PCA 处理后的特征,如果能结合用户设备信息、IP 地址、交易历史,模型可能会更加精准。

6.6 小结

  • 模型性能
    • 召回率从 91.58% 提高到 92.63%,检测到更多欺诈交易。
    • 精确率从 98.86% 提高到 98.88%,减少对正常用户的干扰。
    • AUC 0.98,模型整体表现优异。
  • 业务优化建议
    • 动态调整决策阈值,不同交易类型采取不同策略。
    • 结合时间序列分析,监测欺诈行为的变化趋势。
    • 多维度身份验证,在高风险交易中增加安全防护。
  • 未来改进方向
    • 结合未经过 PCA 处理的原始数据,可能发现更有效的欺诈特征。
    • 引入深度学习模型(如 RNN)处理时间序列数据,提高检测能力。

7. 完整代码

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from imblearn.under_sampling import RandomUnderSampler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report, \
    confusion_matrix
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from xgboost import XGBClassifier

# 读取数据
file_path = "./dataset/009/creditcard.csv"  # 数据文件路径
df = pd.read_csv(file_path)

# 显示数据集的基本信息
print("数据集基本信息:")
print(df.info())

# 显示数据的前几行
print("\n数据集前几行:")
print(df.head())

# 统计数据的基本描述信息
print("\n数据集统计描述:")
print(df.describe())

# 检查缺失值
print("\n数据集中缺失值统计:")
print(df.isnull().sum())

# 检查是否存在无穷大 (inf) 数据
print("\n数据集中是否包含无穷大 (inf) 值:")
print(np.isinf(df.values).sum())

# 检查重复数据
print("\n数据集中重复行的数量:", df.duplicated().sum())

# 如果有重复数据,则删除
df = df.drop_duplicates()
print("去除重复数据后数据集大小:", df.shape)

# 交易金额的分布
plt.figure(figsize=(10, 5))
sns.histplot(df['Amount'], bins=50, kde=True, color='blue')
plt.xlabel("Transaction Amount")
plt.ylabel("Frequency")
plt.title("Distribution of Transaction Amount")
plt.show()

# 交易时间的分布
plt.figure(figsize=(10, 5))
sns.histplot(df['Time'], bins=50, kde=True, color='green')
plt.xlabel("Transaction Time (Seconds)")
plt.ylabel("Frequency")
plt.title("Distribution of Transaction Time")
plt.show()

# 类别分布
plt.figure(figsize=(6, 6))
labels = ["Non-Fraud (0)", "Fraud (1)"]
sizes = df["Class"].value_counts().values
colors = ["#3498db", "#e74c3c"]
plt.pie(sizes, labels=labels, autopct='%1.2f%%', colors=colors, startangle=140, explode=(0, 0.1))
plt.title("Class Distribution")
plt.show()

# 计算相关性矩阵
corr_matrix = df.corr()

# 绘制相关性热力图
plt.figure(figsize=(15, 10))
sns.heatmap(corr_matrix, cmap="coolwarm", annot=False, fmt=".2f")
plt.title("Correlation Heatmap of Features")
plt.show()

# 显示与 Class 相关性最高的前 5 个特征
corr_with_target = corr_matrix["Class"].abs().sort_values(ascending=False)
print("与 Class 相关性最高的前 5 个特征:\n", corr_with_target.head(6))

# 选取与 Class 相关性较高的特征
important_features = ["V10", "V12", "V14", "V17", "V18"]

plt.figure(figsize=(15, 8))
for i, feature in enumerate(important_features, 1):
    plt.subplot(2, 3, i)
    sns.boxplot(x=df["Class"], y=df[feature], palette=["blue", "red"])
    plt.xlabel("Class")
    plt.ylabel(feature)
    plt.title(f"Boxplot of {feature}")
plt.tight_layout()
plt.show()

# 去除无关特征 'Time'
df = df.drop(columns=['Time'])

# 归一化交易金额 'Amount'


scaler = StandardScaler()
df['Amount'] = scaler.fit_transform(df[['Amount']])

# 查看数据处理后的信息
print("数据集处理后信息:")
print(df.head())

X = df.drop(columns=['Class'])  # 选择特征
y = df['Class']  # 目标变量

# 进行欠采样,使欺诈交易和正常交易数量相等
rus = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = rus.fit_resample(X, y)

# 重新合并成 DataFrame
df_resampled = pd.concat([pd.DataFrame(X_resampled, columns=X.columns), pd.DataFrame(y_resampled, columns=['Class'])],
                         axis=1)

# 重新检查类别分布
print("欠采样后数据类别分布:")
print(df_resampled['Class'].value_counts())

# 划分训练集和测试集,80% 作为训练集,20% 作为测试集
X_train, X_test, y_train, y_test = train_test_split(X_resampled, y_resampled, test_size=0.2, random_state=42,
                                                    stratify=y_resampled)

# 输出数据集划分结果
print(f"训练集样本数:{X_train.shape[0]}")
print(f"测试集样本数:{X_test.shape[0]}")

# 计算类别权重,解决类别不均衡问题
fraud_weight = (y_train == 0).sum() / (y_train == 1).sum()

# 定义 XGBoost 模型
model = XGBClassifier(
    scale_pos_weight=fraud_weight,  # 处理类别不均衡
    n_estimators=50,  # 50 棵树
    max_depth=5,  # 树的最大深度
    learning_rate=0.15,  # 学习率
    subsample=0.8,  # 采样比例
    colsample_bytree=0.8,  # 选择部分特征进行训练
    random_state=42
)

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

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

# 计算评估指标
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1 Score: {f1:.4f}")

# 打印分类报告
print("\nClassification Report:\n", classification_report(y_test, y_pred, target_names=['Non-Fraud', 'Fraud']))

import seaborn as sns
import matplotlib.pyplot as plt

# 计算混淆矩阵
cm = confusion_matrix(y_test, y_pred)

# 绘制混淆矩阵热力图
plt.figure(figsize=(6, 6))
sns.heatmap(cm, annot=True, fmt="d", cmap="coolwarm", xticklabels=['Non-Fraud', 'Fraud'],
            yticklabels=['Non-Fraud', 'Fraud'])
plt.xlabel("Predicted Label")
plt.ylabel("True Label")
plt.title("Confusion Matrix")
plt.show()

# 计算预测概率
y_scores = model.predict_proba(X_test)[:, 1]

# 计算 FPR 和 TPR
fpr, tpr, _ = roc_curve(y_test, y_scores)
roc_auc = auc(fpr, tpr)

# 绘制 ROC 曲线
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (AUC = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("Receiver Operating Characteristic (ROC) Curve")
plt.legend(loc="lower right")
plt.show()

# 定义超参数搜索范围
param_dist = {
    'n_estimators': [50, 100, 200, 300],
    'max_depth': [3, 5, 7, 9],
    'learning_rate': [0.01, 0.02, 0.05, 0.08, 0.1, 0.2],
    'subsample': [0.6, 0.8, 1.0],
    'colsample_bytree': [0.6, 0.8, 1.0]
}

# 进行随机搜索
random_search = RandomizedSearchCV(
    estimator=XGBClassifier(scale_pos_weight=fraud_weight, random_state=42),
    param_distributions=param_dist,
    n_iter=20,  # 进行 20 轮搜索
    scoring='f1',  # 选择 F1-score 作为优化目标
    cv=5,  # 3 折交叉验证
    verbose=2,
    random_state=42,
    n_jobs=-1  # 并行计算
)

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

# 输出最佳参数
print("Best Parameters:", random_search.best_params_)

# 使用最优参数训练最终模型
best_model = random_search.best_estimator_

# 预测测试集
y_pred_best = best_model.predict(X_test)

# 计算评估指标
accuracy_best = accuracy_score(y_test, y_pred_best)
precision_best = precision_score(y_test, y_pred_best)
recall_best = recall_score(y_test, y_pred_best)
f1_best = f1_score(y_test, y_pred_best)

print(f"Optimized Accuracy: {accuracy_best:.4f}")
print(f"Optimized Precision: {precision_best:.4f}")
print(f"Optimized Recall: {recall_best:.4f}")
print(f"Optimized F1 Score: {f1_best:.4f}")
© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像-大赛人网
欢迎您留下宝贵的见解!
提交
头像-大赛人网

昵称

取消
昵称

    请登录后查看评论内容