【问题标题】:R confusionMatrix error data and reference factors with same levelsR 混淆矩阵误差数据和参考因素同级别
【发布时间】:2021-03-01 08:03:12
【问题描述】:

在使用 glm 函数进行逻辑回归后,我试图了解如何制作混淆矩阵。到目前为止,这是我的代码。我正在使用 caret 包和confusionMatrix 函数。

dput(head(wine_quality))

structure(list(fixed.acidity = c(7, 6.3, 8.1, 7.2, 7.2, 8.1), 
    volatile.acidity = c(0.27, 0.3, 0.28, 0.23, 0.23, 0.28), 
    citric.acid = c(0.36, 0.34, 0.4, 0.32, 0.32, 0.4), residual.sugar = c(20.7, 
    1.6, 6.9, 8.5, 8.5, 6.9), chlorides = c(0.045, 0.049, 0.05, 
    0.058, 0.058, 0.05), free.sulfur.dioxide = c(45, 14, 30, 
    47, 47, 30), total.sulfur.dioxide = c(170, 132, 97, 186, 
    186, 97), density = c(1.001, 0.994, 0.9951, 0.9956, 0.9956, 
    0.9951), pH = c(3, 3.3, 3.26, 3.19, 3.19, 3.26), sulphates = c(0.45, 
    0.49, 0.44, 0.4, 0.4, 0.44), alcohol = c(8.8, 9.5, 10.1, 
    9.9, 9.9, 10.1), quality = structure(c(4L, 4L, 4L, 4L, 4L, 
    4L), .Label = c("3", "4", "5", "6", "7", "8", "9", "white"
    ), class = "factor"), type = structure(c(3L, 3L, 3L, 3L, 
    3L, 3L), .Label = c("", "red", "white"), class = "factor"), 
    numeric_type = c(0, 0, 0, 0, 0, 0)), row.names = c(NA, 6L
), class = "data.frame")

library(tibble) 
library(broom) 
library(ggplot2)
library(caret)

any(is.na(wine_quality)) # this evaulates to FALSE 


wine_model <- glm(type ~ fixed.acidity + volatile.acidity + citric.acid + residual.sugar +  chlorides + free.sulfur.dioxide + total.sulfur.dioxide + density + pH + sulphates + alcohol, wine_quality, family = "binomial")


# split data into test and train

smp_size <- floor(0.75 * nrow(wine_quality))

set.seed(123)
train_ind <- sample(seq_len(nrow(wine_quality)), size = smp_size)

train <- wine_quality[train_ind, ]
test <- wine_quality[-train_ind, ]


# make prediction on train data

pred <- predict(wine_model)

train$fixed.acidity <- as.numeric(train$fixed.acidity)
round(train$fixed.acidity)
train$fixed.acidity <- as.factor(train$fixed.acidity)

pred <- as.numeric(pred)
round(pred)
pred <- as.factor(pred)

confusionMatrix(pred, wine_quality$fixed.acidity)

在这最后一行代码之后,我得到了这个错误:

Error: `data` and `reference` should be factors with the same levels.

这个错误对我来说没有意义。我已经测试过 pred 的长度和 fixed.acidity 的长度都相同(6497),而且它们都是因子数据类型。

length(pred)
length(wine_quality$fixed.acidity)

class(pred)
class(train$fixed.acidity)

这个混淆矩阵不起作用有什么明显的原因吗?我正在尝试找到模型的命中率。我会很感激虚拟的解释,我真的不知道我在这里做什么。

【问题讨论】:

    标签: r r-caret


    【解决方案1】:

    来自confusionMatrix() 的错误告诉我们传递给函数的两个变量需要是具有相同值的因子。当我们对这两个变量运行 str() 时,我们可以看到为什么会收到错误消息。

    > str(pred)
     Factor w/ 5318 levels "-23.6495182533792",..: 310 339 419 1105 310 353 1062 942 594 1272 ...
    > str(wine_quality$fixed.acidity)
     num [1:6497] 7.4 7.8 7.8 11.2 7.4 7.4 7.9 7.3 7.8 7.5 ...
    

    pred 是一个因子,而 wine_quality$fixed_acidity 是一个数值向量。 confusionMatrix() 函数用于比较因变量的预测值和实际值。它不打算将预测变量和自变量交叉制表。

    问题中的代码在混淆矩阵中使用fixed.acidity,它应该将type 的预测值与测试数据中type 的实际值进行比较。

    此外,问题中的代码会在将数据拆分为测试数据和训练数据之前创建模型。正确的程序是在训练数据上建立模型之前拆分数据,使用测试(保留)数据进行预测,并将实际数据与测试数据中的预测进行比较。

    最后,原帖中编码的predict() 函数的结果是来自 GLM 模型的线性预测值(相当于输出模型对象中的wine_model$linear.predictors)。在用于confusionMatrix() 之前,必须进一步转换这些值以使其适合。

    在实践中,将caret::train() 与 GLM 方法和二项式系列一起使用会更容易,其中predict() 将生成可用于confusionMatrix() 的结果。我们将用 UCI 葡萄酒质量数据来说明这一点。

    首先,我们从 UCI 机器学习存储库下载数据以使示例可重现。

    download.file("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv",
                  "./data/wine_quality_red.csv")
    download.file("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv",
                  "./data/wine_quality_white.csv")
    

    其次,我们加载数据,根据数据文件将type分配为红色或白色,并将数据绑定到单个数据帧中。

    red <- read.csv("./data/wine_quality_red.csv",header = TRUE,sep=";")
    white <- read.csv("./data/wine_quality_white.csv",header = TRUE,sep=";")
    red$type <- "red"
    white$type <- "white"   
    wine_quality <- rbind(red,white)
    wine_quality$type <- factor(wine_quality$type)
    

    接下来,我们根据type 的值将数据分为测试和训练,这样每个数据帧都会获得成比例的红葡萄酒和白葡萄酒,使用默认的caret::train() 设置和 GLM 方法训练数据。

    library(caret)
    set.seed(123)
    inTrain <- createDataPartition(wine_quality$type, p = 3/4)[[1]]
    training <- wine_quality[ inTrain,]
    testing <- wine_quality[-inTrain,]
    
    aModel <- train(type ~ .,data = training, method="glm", familia's = "binomial")
    

    最后,我们使用模型对保留数据框进行预测,并运行混淆矩阵。

    testLM <- predict(aModel,testing)
    confusionMatrix(data=testLM,reference=testing$type)
    

    ...和输出:

    > confusionMatrix(data=testLM,reference=testing$type)
    Confusion Matrix and Statistics
    
              Reference
    Prediction  red white
         red    393     3
         white    6  1221
                                              
                   Accuracy : 0.9945          
                     95% CI : (0.9895, 0.9975)
        No Information Rate : 0.7542          
        P-Value [Acc > NIR] : <2e-16          
                                              
                      Kappa : 0.985           
                                              
     Mcnemar's Test P-Value : 0.505           
                                              
                Sensitivity : 0.9850          
                Specificity : 0.9975          
             Pos Pred Value : 0.9924          
             Neg Pred Value : 0.9951          
                 Prevalence : 0.2458          
             Detection Rate : 0.2421          
       Detection Prevalence : 0.2440          
          Balanced Accuracy : 0.9913          
                                              
           'Positive' Class : red   
    

    【讨论】:

      猜你喜欢
      • 2017-03-23
      • 2015-07-12
      • 2021-03-18
      • 2019-11-21
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      相关资源
      最近更新 更多