R中confusionMatrix报错:无法提取统计量($运算符对原子向量无效)
问题:caret包confusionMatrix报错无法提取性能指标
代码实现
if(!require(caret)) install.packages('caret') library(caret) if(!require(class)) install.packages('class') library(class) if(!require(data.table)) install.packages('data.table') library(data.table) # used for fread if(!require(e1071)) install.packages('e1071') library(e1071) if(!require(ggplot2)) install.packages('ggplot2') library(ggplot2) if(!require(knitr)) install.packages('knitr') library(knitr) if(!require(kableExtra)) install.packages('kableExtra') install.packages("kableExtra") if(!require(MLmetrics)) install.packages('MLmetrics') library(ModelMetrics) if(!require(randomForest)) install.packages('randomForest') library(randomForest) if(!require(reshape2)) install.packages('reshape2') library(reshape2) if(!require(tidyverse)) install.packages('tidyverse') library(tidyverse) if(!require(tidyr)) install.packages('tidyr') library(tidyr) dataset_url <- "https://archive.ics.uci.edu/static/public/332/online+news+popularity.zip" # Download and extract the dataset temp_dir <- tempdir() temp_file <- file.path(temp_dir, "online_news_popularity.zip") download.file(dataset_url, temp_file) unzip(temp_file, exdir = temp_dir) # Load the dataset into a data.table data <- fread(file.path(temp_dir, "OnlineNewsPopularity/OnlineNewsPopularity.csv")) shares01 <- rep(0, length(data$shares)) # initializes a new variable shares01 that has same length as shares and initial value set to 0 shares01[data$shares > median(data$shares)] <- 1 # popular articles are defined as 1 set.seed(1, sample.kind="Rounding") #Removing non predictive variables data <- subset( data, select = -c(url, timedelta,is_weekend) ) # Scaling by subtracting the mean and dividing by the standard dev data <- subset(data,select=-c(shares)) data <- data.frame(data,shares01) # Identify the columns to be scaled (exclude "shares01" column) cols_to_scale <- setdiff(names(data), "shares01") # Scale the selected columns in the data frame scaled_data <- data scaled_data[cols_to_scale] <- lapply(data[cols_to_scale], scale) #generating indexing for randomly splitting the main dataset into training and test sets initial_index <- createDataPartition(y = scaled_data$shares01, times = 1, p = 0.98, list = FALSE) train_set <- scaled_data[-initial_index,] test_set <- scaled_data[initial_index,] #generating indexing for randomly further splitting the train data into training and test sets initial_index <- createDataPartition(y = train_set$shares01, times = 1, p = 0.9, list = FALSE) train_train_set <- train_set[-initial_index,] train_test_set <- train_set[initial_index,] # Create the trainControl object for cross-validation settings ctrl_rf <- trainControl(method = "cv", number = 5) #cv method stands for k-cross fold validation which is 5 in this case. # Train the Random Forest model using cross-validation model_rf <- train(shares01 ~ ., data = train_train_set, method = "rf", trControl = ctrl_rf) # Make predictions on the test set using the trained model predictions_rf <- predict(model_rf, newdata = train_test_set) # Actual values of the response variable in the test set actual_values <- as.factor(train_test_set$shares01) # Create the confusion matrix conf_matrix_rf <- confusionMatrix(actual_values,predictions_rf) # Extract metrics accuracy_rf <- conf_matrix_rf$overall["Accuracy"]
报错信息
> accuracy_rf <- conf_matrix_rf$overall["Accuracy"] Error in conf_matrix_rf$overall : $ operator is invalid for atomic vectors
异常情况
使用confusionMatrix生成的混淆矩阵结果不正确,但手动通过table函数计算的混淆矩阵及相关评估指标是正确的:
# Confusion matrix conf_matrix <- table(predictions_rf, actual_values) # Calculate True Positives (TP), True Negatives (TN), False Positives (FP), and False Negatives (FN) TP_rf <- conf_matrix[2, 2] TN_rf <- conf_matrix[1, 1] FP_rf <- conf_matrix[1, 2] FN_rf <- conf_matrix[2, 1] accuracy_rf <- (TP_rf + TN_rf) / (TP_rf + TN_rf + FP_rf + FN_rf) precision_rf <- TP_rf / (TP_rf + FP_rf) recall_rf <- TP_rf / (TP_rf + FN_rf) f1_score_rf <- 2 * (precision_rf * recall_rf) / (precision_rf + recall_rf)
解决方案
核心问题:参数顺序错误
caret包的confusionMatrix()函数要求第一个参数是预测值,第二个参数是真实值(reference),你写反了参数顺序,导致函数仅返回原子向量格式的混淆矩阵表格,而非包含统计量的列表,因此无法用$提取overall指标。
修正步骤
- 调整
confusionMatrix的参数顺序,或显式指定参数(推荐后者,更清晰):
# 方式1:调整参数顺序(预测值在前,真实值在后) conf_matrix_rf <- confusionMatrix(predictions_rf, actual_values) # 方式2:显式指定参数 conf_matrix_rf <- confusionMatrix(data = predictions_rf, reference = actual_values)
- 确保预测值与真实值的因子水平一致(可选但避免潜在问题):
如果predictions_rf不是因子类型,先转换为和actual_values相同水平的因子:
predictions_rf <- factor(predictions_rf, levels = levels(actual_values))
- 重新提取性能指标:
accuracy_rf <- conf_matrix_rf$overall["Accuracy"] precision_rf <- conf_matrix_rf$byClass["Precision"] recall_rf <- conf_matrix_rf$byClass["Recall"] f1_score_rf <- conf_matrix_rf$byClass["F1"]
调整后conf_matrix_rf会返回包含混淆矩阵、总体性能指标、分类细节指标的完整列表,即可正常提取所需参数。
内容的提问来源于stack exchange,提问作者munib ullah
相关产品推荐
相关产品推荐

