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

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指标。

修正步骤

  1. 调整confusionMatrix的参数顺序,或显式指定参数(推荐后者,更清晰):
# 方式1:调整参数顺序(预测值在前,真实值在后)
conf_matrix_rf <- confusionMatrix(predictions_rf, actual_values)

# 方式2:显式指定参数
conf_matrix_rf <- confusionMatrix(data = predictions_rf, reference = actual_values)
  1. 确保预测值与真实值的因子水平一致(可选但避免潜在问题):
    如果predictions_rf不是因子类型,先转换为和actual_values相同水平的因子:
predictions_rf <- factor(predictions_rf, levels = levels(actual_values))
  1. 重新提取性能指标:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:36:03