You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tensorflow欺诈交易预测模型混淆矩阵全零问题求助

解决欺诈检测模型全预测0的问题

你的混淆矩阵显示所有样本都被预测为类别0,说明模型完全没有学到识别欺诈样本(类别1)的能力,以下是针对性的修复方案:

1. 调整数据拆分策略,保留足够训练样本

你当前设置test_size=0.95,导致训练集仅占总数据的5%,对于极度不平衡的数据集来说,训练集中的欺诈样本数量会少到可以忽略,SMOTE过采样也无法弥补样本量不足的问题。修改拆分逻辑,同时加入stratify参数保证各集合的类别比例与原数据一致:

# 先拆分训练+验证集与测试集(测试集占20%)
X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 再从训练+验证集中拆分训练集与验证集(验证集占训练+验证集的20%)
X_train, X_val, y_train, y_val = train_test_split(X_train_val, y_train_val, test_size=0.2, random_state=42, stratify=y_train_val)

# 再对训练集应用SMOTE过采样
sm = SMOTE(random_state=42)
X_train, y_train = sm.fit_resample(X_train, y_train)

2. 正确使用归一化层

Keras的Normalization层需要先在训练数据上执行adapt操作,才能学习到训练集的均值和方差用于归一化,否则该层无法发挥作用:

# 初始化并适配归一化层到训练数据
normalizer = layers.Normalization()
normalizer.adapt(X_train)

model = models.Sequential()
model.add(normalizer)  # 使用适配后的归一化层
model.add(layers.Dense(25, activation="relu"))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(10, activation="relu"))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(5, activation="relu"))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(1, activation="sigmoid"))

3. 添加早停回调,避免过拟合/无意义训练

训练100个epoch容易导致过拟合或无效训练,加入早停回调监控验证集的Recall(核心目标是识别欺诈样本),自动停止并恢复最佳模型权重:

model.compile(optimizer="Adam", loss="binary_crossentropy", metrics=["Precision", "Recall", "AUC"])

# 早停配置:监控验证集Recall,10个epoch无提升则停止,恢复最佳权重
early_stopping = EarlyStopping(monitor='val_recall', patience=10, restore_best_weights=True, mode='max')
history = model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=100, callbacks=[early_stopping])

4. 优化特征工程(可选但有效)

针对Time和Amount特征做针对性处理,提升模型学习效率:

  • Time:转换为小时数,捕捉交易时间规律
  • Amount:对数变换,缓解金额的长尾分布影响
# 特征工程要在数据拆分前执行
# Time转换为小时(一天86400秒)
X['Time'] = X['Time'] % 86400 / 3600
# Amount做对数变换(log1p避免0值报错)
X['Amount'] = np.log1p(X['Amount'])

5. 引入类别权重(可选)

即使使用了SMOTE,也可以给欺诈样本分配更高的类别权重,让模型更重视欺诈样本的分类错误:

from sklearn.utils.class_weight import compute_class_weight

# 计算平衡的类别权重
class_weights = compute_class_weight('balanced', classes=np.unique(y_train), y=y_train)
class_weight_dict = {0: class_weights[0], 1: class_weights[1]}

# 在fit时传入类别权重
history = model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=100, callbacks=[early_stopping], class_weight=class_weight_dict)

完成以上修改后,重新训练模型,再评估混淆矩阵和Recall、AUC等指标,应该能看到模型开始识别欺诈样本。

内容的提问来源于stack exchange,提问作者Lapin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:09:57