如何在R中绘制与roc.glmnet风格一致的Logistic回归及随机森林ROC曲线
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 oftype = "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
pROCpackage is flexible enough to matchglmnet'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

