预测与实际绘图

15

我对R编程和统计学还很陌生,不知道如何在进行多元线性回归后绘制预测值与实际值的图形。我曾看到过类似的问题(但是无法理解代码),如果您能够帮忙解释代码,我将非常感激。

# Attach file containing variables and responses
q <- read.csv("C:/Users/A/Documents/Design.csv")
attach(q)
# Run a linear regression
model <- lm(qo~P+P1+P4+I)
# Summary of linear regression results
summary(model)

预测值与实际值的图表可以帮助我直观地看到回归模型与实际数据拟合的程度。


你的模型是线性回归模型,因此R-sqr应该给出模型的准确度。这不是一个典型的分类问题,无需预测与实际情况的图表。 - amrrs
你能包含你所遇到的吗? - Sotos
正如@Ben Bolker刚刚发布的那样,您可以例如使用ablineplot 进一步阅读: https://stat.ethz.ch/pipermail/r-help//2013-February/347479.html - nilsole
@amrrs 是的,那是一种方法,但我想看到它的图形表示。 - John
@nilsole 谢谢链接 - John
4个回答

22

如果您提供一个可重现的示例将更好,但这是我编写的一个示例:

set.seed(101)
dd <- data.frame(x=rnorm(100),y=rnorm(100),
                 z=rnorm(100))
dd$w <- with(dd,
     rnorm(100,mean=x+2*y+z,sd=0.5))

使用data参数会更好——几乎不应该使用attach()..

 m <- lm(w~x+y+z,dd)
 plot(predict(m),dd$w,
      xlab="predicted",ylab="actual")
 abline(a=0,b=1)

输入图像描述


1
嗨@Ben Bolker。谢谢你的回复。只是确认我理解了。在运行回归之后,我只需要使用预测参数来让r根据我的回归生成预测值,然后将我的预测值与计算/实验值绘制在一起,是这样吗? - John
您还可以直接从模型中调用拟合值,使用 m$fitted.values 而不是使用 predict() - Seanosapien
最佳实践(在我看来)是尽可能使用像predict()这样的访问器;它们通常更灵活,并且可以安全地用于各种模型类型(如果模型对象的内部结构在将来发生变化,它们仍将起作用)。 - Ben Bolker

11
除了 预测 vs 实际 绘图外,您还可以获得另一组绘图,帮助您在视觉上评估拟合度的好坏。

除了预测 vs 实际绘图之外,您还可以获得其他一组绘图,以帮助您直观地评估拟合效果。

--- execute previous code by Ben Bolker ---

par(mfrow = c(2, 2))
plot(m)

在此输入图片描述


2
一种整洁的方法是使用modelsummary::augment()函数:
library(tidyverse)
library(cowplot)
library(modelsummary)

set.seed(101)
# Using Ben's data above:
dd <- data.frame(x=rnorm(100),y=rnorm(100),
                 z=rnorm(100))
dd$w <- with(dd,rnorm(100,mean=x+2*y+z,sd=0.5))

m <- lm(w~x+y+z,dd)

m %>% augment() %>% 
  ggplot()  + 
  geom_point(aes(.fitted, w)) + 
  geom_smooth(aes(.fitted, w), method = "lm", se = FALSE, color = "lightgrey") + 
labs(x = "Actual", y = "Fitted") + 
  theme_bw()

这对于深度嵌套的回归列表尤其有效。
为了说明这一点,考虑一些嵌套的回归列表:
Reglist <- list()

Reglist$Reg1 <- dd %>% do(reg = lm(as.formula("w~x*y*z"), data = .)) %>% mutate( Name = "Type 1")
Reglist$Reg2 <- dd %>% do(reg = lm(as.formula("w~x+y*z"), data = .)) %>% mutate( Name = "Type 2")
Reglist$Reg3 <- dd %>% do(reg = lm(as.formula("w~x"), data = .)) %>% mutate( Name = "Type 3")
Reglist$Reg4 <- dd %>% do(reg = lm(as.formula("w~x+z"), data = .)) %>% mutate( Name = "Type 4")

现在,以上整洁的绘图框架的强大之处就得以体现...
Graph_Creator <- function(Reglist){

  Reglist %>% pull(reg) %>% .[[1]] %>% augment() %>% 
    ggplot()  + 
    geom_point(aes(.fitted, w)) + 
    geom_smooth(aes(.fitted, w), method = "lm", se = FALSE, color = "lightgrey") + 
    labs(x = "Actual", y = "Fitted", 
         title =  paste0("Regression Type: ", Reglist$Name) ) + 
    theme_bw()
}

Reglist %>% map(~Graph_Creator(.)) %>% 
  cowplot::plot_grid(plotlist = ., ncol = 1)

enter image description here


我仍然对tidyverse的做事方式持怀疑态度... ggplot很棒,没有回头路。但是其他部分似乎是不必要的违背了R风格的偏离。例如,为什么要使用m %>% augment() %>% ...?我觉得使用基本的R + data.table可以在不太影响通常的R的情况下获得相同的功能。这不是批评,我只是试图理解我看到的所有对tidyverse的热情... - dariober
1
大声朗读一下代码,并用“then”替换%>%,这样读起来就像一本小说,这让阅读和理解他人(以及过去的自己)的代码变得更加容易。data.table缺乏任何合理的语法解释(你今天能看懂自己的代码,但未来解释它将是一项任务)。 - Nick

1
与@Ben Bolker的解决方案相同,但获取ggplot对象而不是使用基本R。
#first generate the dd data set using the code in Ben's solution, then... 

require(ggpubr)
m <- lm(w~x+y+z,dd)

ggscatter(x = "prediction",
          y = "actual",
          data = data.frame(prediction = predict(m),
                            actual = dd$w)) +
  geom_abline(intercept = 0,
              slope = 1) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接