R中基于Keras的MLP贷款预测模型训练验证准率高但测试集性能差求助
MLP贷款准入预测模型测试性能异常问题
更新
为帮助遇到同类问题的用户,我后续通过平衡数据集成功提升了AUC,具体代码修改如下:
history <- model %>% fit(train_nn, train_target, # 使用独热编码时替换为train_label epoch = 100, batch_size = 32, validation_split = 0.10, class_weight = list("0" = nrow(dataset[dataset[,134] == 1,])/nrow(dataset[dataset[,134] == 0,]), "1" = 1)
更新结束
问题背景
我目前正在研究神经网络模型的预测偏差问题,使用金融科技公司Bondora的数据集构建MLP模型用于贷款准入预测。数据集包含多个分类变量与数值变量,我构建了目标分类变量reject_loan:若贷款发放后1年内违约则标注为1,否则为0,本次任务为基于MLP预测该目标变量。
问题描述
尽管模型训练准确率约83%、验证准确率约90%,但测试集预测性能极差:模型通常对所有样本仅预测同一类别,仅能极少数正确预测另一类别,AUC始终在50%左右。
已尝试的优化方案
- 所有分类变量(含目标变量)做独热编码,数值变量归一化,隐藏层使用relu激活函数,输出层使用softmax激活函数,损失函数采用分类交叉熵
- 不做独热编码,数值变量归一化,隐藏层使用relu激活函数,输出层使用sigmoid激活函数,损失函数采用二元交叉熵
- 隐藏层改用elu激活函数,避免relu的神经元坏死问题
- 调整隐藏层数量,分别测试加入L1、L2正则与不加正则的效果
- 加入Dropout层
- 分别测试SGD、Adam优化器
- 降低学习率,最低测试值为0.000001
以上方案均未提升模型预测性能。另外我在同一数据集上训练XGBoost模型可达到约90%的AUC,恳请各位帮忙排查问题原因,我的模型代码如下:
# 划分训练集测试集 set.seed(1234) # 按8:2比例划分训练集和测试集 sample <- sample(2, nrow(dataset), replace = T, prob = c(0.80,0.20)) train <- dataset[sample==1,1:ncol(dataset)-1] test <- dataset[sample==2,1:ncol(dataset)-1] train_target <- dataset[sample==1, ncol(dataset)] test_target <- dataset[sample==2, ncol(dataset)] # 独热编码 train_label <- to_categorical(train_target) test_label <- to_categorical(test_target) # 构建序列化模型 model <- keras_model_sequential() model %>% layer_dense(units = 16, activation = 'elu', input_shape = c(ncol(train_nn)), kernel_regularizer = regularizer_l1_l2(l1 = 0.2, l2 = 0.2)) %>% layer_dropout(0.2) %>% layer_dense(units = 8, activation = 'elu', kernel_regularizer = regularizer_l1_l2(l1 = 0.2, l2 = 0.2)) %>% layer_dropout(0.4) %>% layer_dense(units = 8, activation = 'elu') %>% layer_dense(units = 1, activation = 'sigmoid' # 本轮迭代使用sigmoid,若目标变量做独热编码可使用softmax,输出维度设为2 ) # 编译模型 opt = optimizer_sgd(lr = 0.001, momentum = 0, decay = 0, nesterov = FALSE, clipnorm = NULL, clipvalue = NULL ) opt2 = optimizer_adam(lr = 0.000001, beta_1 = 0.9, beta_2 = 0.999, epsilon = NULL, decay = 0, amsgrad = FALSE, clipnorm = NULL, clipvalue = NULL ) model %>% compile(loss = 'binary_crossentropy', # 部分迭代中使用分类交叉熵 optimizer = opt2, metrics = 'accuracy') # 拟合模型 clbck = callback_reduce_lr_on_plateau(monitor='val_loss', factor=0.1, patience=2) history <- model %>% fit(train_nn, train_target, # 使用独热编码时替换为train_label epoch = 100, batch_size = 32, validation_split = 0.10) # 用测试集评估模型 nn_model_3 <- model %>% evaluate(test, test_target) # 使用独热编码时替换为test_label # 测试集预测与混淆矩阵 prob <- model %>% predict_proba(test) pred <- model %>% predict_classes(test) nn_conf_table_3 <- table(Predicted = pred, Actual = test_target) nn_probability_table_3 <- cbind(prob, pred, test_target) # 计算AUC与ROC曲线 par(pty = "s") nn_roc_3 <- roc(test_target, pred, plot=T, percent=T, lwd = 3, print.auc=T)
内容的提问来源于stack exchange,提问作者Sayan Ray
相关产品推荐
相关产品推荐

