使用神经网络验证Amex校验位:输出为概率数组而非预期值1的问题
解决Amex校验位神经网络模型输出不符合预期的问题
首先,先帮你梳理下核心问题:你的模型准确率很高,但测试输入的预测概率数组里,概率最高的是索引7的类别(99.4%),而不是预期的索引1,这大概率是标签与输出层索引的映射错位,加上测试集标准化的小错误导致的。下面一步步给你解决:
1. 先修正测试集标准化的错误
你这里犯了一个常见的预处理错误:测试集不能重新做fit_transform,必须用训练集的scaler来做transform,否则会破坏训练集和测试集的数据分布一致性,直接影响预测结果。
把这段代码:
x_test = sc.fit_transform(x_test)
改成:
x_test = sc.transform(x_test)
修正后重新训练模型,这是基础前提。
2. 确认标签与输出层的对应关系
Amex的校验位是0-9的数值,你的输出层是units=10的softmax,对应0-9共10个类别,所以需要确保训练时的标签Y里的数值,和输出层的索引完全对应(比如校验位1对应输出层的索引1)。
你可以先检查训练数据里的标签分布,确认数值范围和对应关系:
print("校验位数值分布:") print(data.iloc[:, -1].value_counts().sort_index())
如果发现标签里的数值不是0-9(比如是1-10),那需要把标签转换为0-9的索引形式:
# 如果校验位是1-10,转成0-9的索引 Y = data.iloc[:, -1].values - 1
这样训练后,模型输出的索引就和校验位数值直接对应(索引+1就是原数值,如果是1-10的情况;如果原本就是0-9,索引就是数值)。
3. 将预测概率转换为实际校验位数值
当模型输出概率数组后,你需要找到概率最大的索引,再映射为对应的校验位数值。比如:
# 输入测试数据并标准化 test_input = sc.transform([[3,7,9,8,8,1,4,4,7,0,4,5,2,6]]) # 获取预测概率 pred_probs = ann.predict(test_input) # 找到概率最高的索引 pred_index = np.argmax(pred_probs) # 根据标签的实际情况映射为校验位: # 情况1:标签原本就是0-9,直接用索引作为校验位 pred_checkdigit = pred_index # 情况2:标签原本是1-10,索引加1得到校验位 # pred_checkdigit = pred_index + 1 print(f"预测的校验位数值:{pred_checkdigit}")
4. 额外检查:模型训练的标签是否错位
如果修正了上面的问题后还是不对,那要检查训练数据里的标签是否和特征对应错误(比如把校验位列和其他列搞混了)。你可以打印几条数据的特征和标签,确认对应关系:
print(data[["你最后一列的列名"]].head()) # 替换成实际的校验位列名 print(data.iloc[:, :-1].head()) # 打印特征列,确认是前14位卡号
按照上面的步骤修正后,模型应该能输出预期的校验位数值1了。
内容的提问来源于stack exchange,提问作者AlphaTK
相关产品推荐
相关产品推荐

