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

如何在R中绘制与roc.glmnet风格一致的Logistic回归及随机森林ROC曲线

Fixing ROC Curve Styling for Logistic Regression & Random Forest (Matching LASSO's Aesthetic)

I see exactly what's going on here—your current approach uses hard classification results (0/1 predicted labels) instead of predicted probabilities to calculate ROC curves, which is why you're stuck with those rough, two-point lines. Plus, we can standardize all three models' plots to match the polished style of glmnet's built-in ROC plot using the pROC package. Let's break this down step by step:

Why Your Current Code Fails

  • For Random Forest: You’re using as.numeric(rf.pred_SUM_db$predict) (the hard-classified 0/1 values) instead of the predicted probabilities of the positive class. This only gives you one threshold (0.5), resulting in a jagged line with just two data points.
  • For Logistic Regression: If you’ve been using predict(type = "class") instead of type = "response", you’ll hit the same issue—only one threshold, no smooth curve to show model performance across all cutoff points.

Step 1: Fix Random Forest ROC Calculation

Let’s adjust your Random Forest code to use positive-class probabilities instead of hard predictions:

# Load required packages
library(randomForest)
library(pROC)

# Keep your existing model fitting code
df_train_logit_rf_class$export_future <- as.factor(df_train_logit_rf_class$export_future)
df_test_rf_class$export_future <- as.factor(df_test_rf_class$export_future)

rf.fit_SUM_classification <- randomForest(
  formula = export_future ~ ., 
  data = df_train_logit_rf_class, 
  ntree = 500, 
  maxnodes = 100, 
  norm.votes = FALSE
)

# Extract POSITIVE CLASS probabilities (check colnames(rf.pred_SUM_db) to confirm column name)
rf.pred_SUM_db <- as.data.frame(predict(rf.fit_SUM_classification, df_test_rf_class, type = "prob"))
rf_pos_prob <- rf.pred_SUM_db[, "1"]  # Assumes "1" is your positive class (export_future=1)

# Calculate ROC using probabilities (not hard predictions!)
rf_roc <- roc(
  response = df_test_rf_class$export_future,  # pROC handles factor variables directly
  predictor = rf_pos_prob,
  levels = c("0", "1")  # Specify order: negative class first, positive second
)

Step 2: Fix Logistic Regression ROC Calculation

For Logistic Regression, we’ll follow the same rule—use predicted probabilities instead of class labels:

# Fit Logistic Regression model
logit_fit <- glm(
  formula = export_future ~ ., 
  data = df_train_logit_rf_class, 
  family = binomial(link = "logit")
)

# Extract positive class probabilities
logit_pos_prob <- predict(logit_fit, newdata = df_test_rf_class, type = "response")

# Calculate ROC
logit_roc <- roc(
  response = df_test_rf_class$export_future,
  predictor = logit_pos_prob,
  levels = c("0", "1")
)

Step 3: Prepare LASSO ROC for Unified Plotting

Your existing roc.glmnet call generates a valid ROC object, but we can convert it to a pROC object for consistent styling (or use it directly in plots):

library(glmnet)

# Use your existing LASSO fit
lasso_roc_obj <- roc.glmnet(lasso.fit_SUM, newx = x.train.loop, newy = y.train.loop)[[10]]
# Optional: Convert to pROC object for full styling control
lasso_roc <- roc(
  response = y.train.loop,
  predictor = predict(lasso.fit_SUM, newx = x.train.loop, s = lasso.fit_SUM$lambda[10], type = "response")
)

Step 4: Plot All Curves with Matching Aesthetics

Now we’ll plot all three curves using pROC's plot() function, which replicates the clean, informative style of glmnet's default ROC plot (grid lines, AUC labels, smooth curves):

# Initialize plot with LASSO curve (base style matching glmnet)
plot(
  lasso_roc,
  col = "#1f77b4",  # Blue (matches glmnet's default)
  lwd = 2,
  main = "ROC Curves: LASSO vs. Logistic vs. Random Forest",
  grid = TRUE,  # Add grid lines like glmnet's plot
  print.auc = TRUE,  # Display AUC value
  print.auc.col = "#1f77b4",
  legacy.axes = TRUE  # Use 1-Specificity on x-axis (matches glmnet's output)
)

# Add Logistic Regression curve
lines(
  logit_roc,
  col = "#ff7f0e",  # Orange
  lwd = 2,
  print.auc = TRUE,
  print.auc.y = 0.4,  # Position AUC label below LASSO's
  print.auc.col = "#ff7f0e"
)

# Add Random Forest curve
lines(
  rf_roc,
  col = "#2ca02c",  # Green
  lwd = 2,
  print.auc = TRUE,
  print.auc.y = 0.3,  # Position AUC label below Logistic's
  print.auc.col = "#2ca02c"
)

# Add clean legend
legend(
  "bottomright",
  legend = c("LASSO", "Logistic Regression", "Random Forest"),
  col = c("#1f77b4", "#ff7f0e", "#2ca02c"),
  lwd = 2,
  bty = "n"  # Remove legend border for a polished look
)

Key Takeaways

  • Always use predicted probabilities (not hard classifications) for ROC curves—this gives you all possible threshold values, resulting in a smooth, informative curve that reflects model performance across cutoff points.
  • The pROC package is flexible enough to match glmnet's aesthetic while letting you compare multiple models in a single plot.
  • Double-check your positive class order in the roc() function to ensure the curve is calculated correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:37:49