我可以使用什么测试来比较两个或多个回归模型的斜率?


29

我想测试两个变量对一个预测变量的响应差异。这是一个最小的可复制示例。

library(nlme) 
## gls is used in the application; lm would suffice for this example
m.set <- gls(Sepal.Length ~ Petal.Width, data = iris, 
               subset = Species == "setosa")
m.vir <- gls(Sepal.Length ~ Petal.Width, data = iris, 
               subset = Species == "virginica")
m.ver <- gls(Sepal.Length ~ Petal.Width, data = iris, 
               subset = Species == "versicolor")

我可以看到斜率系数是不同的:

m.set$coefficients
(Intercept) Petal.Width 
  4.7771775   0.9301727
m.vir$coefficients
(Intercept) Petal.Width 
  5.2694172   0.6508306 
m.ver$coefficients
(Intercept) Petal.Width 
   4.044640    1.426365 

我有三个问题:

  1. 如何测试斜率之间的差异?
  2. 如何测试残差之间的差异?
  3. 进行这些比较的一种简单有效的方法是什么?

一个相关的问题,即在两个回归模型中比较变量系数的方法,建议使用虚拟变量重新运行该模型以区分斜率,是否存在允许使用独立数据集的选项?


关于第一个问题,请参阅stats.stackexchange.com/questions/55501/…
russellpierce

Answers:


22

如何测试斜率之间的差异?

包括一个物种的虚拟对象,使其与交互,并查看该虚拟对象是否有意义。令为萼片长度,为踏板宽度,为这三种动物的虚拟变量。比较模型L i P i S 1S 2S 3PiLiPiS1,S2,S3

E(Li)=β0+β1Pi

使用允许每个物种的效果不同的模型:Pi

E(Li)=α0+α1S2+α2S3+α4Pi+α5PiS2+α6PiS3

GLS估计量是MLE,第一个模型是第二个模型的子模型,因此您可以在此处使用似然比检验。可以使用logLik函数来提取可能性,并且测试的自由度为因为您已经删除了参数以到达子模型。444

呈现比较的一种简单有效的方法是什么?

我认为最吸引人的方法是在同一轴上绘制每个物种的回归线,也许使用基于标准误差的误差线。这将使物种之间的差异(或非差异)及其与的关系非常明显。Pi

编辑:我注意到另一个问题已添加到正文。因此,我为此添加了一个答案:

如何测试残差之间的差异?

为此,您需要对数据集进行分层,并拟合单独的模型,因为我建议的基于交互的模型会将残差方差约束为每组相同。如果适合单独的模型,则此约束将消失。在那种情况下,您仍然可以使用似然比检验(现在通过将三个独立模型的似然值相加来计算较大模型的似然值)。“空”模型取决于您要与之比较的模型

  • 如果你只是想测试的变化,同时使主效应,那么“空”的模式应该是与我上面写的交互模型。这样,测试的自由度为。2

  • 如果要与系数一起测试方差,则空模型应该是我上面编写的第一个模型。这样,测试的自由度为。6


为什么第二个模型中没有?是否正确实施的R模式?S1gls(Sepal.Length ~ species:Petal.Width, data = iris)
安倍

嗨@安倍 是“参考”种类-该种类的回归线由。如果是分类变量,那么我认为应该是语法。α 0 + α 4 P S1α0+α4Pispeciesgls(Sepal.Length ~ species*Petal.Width, data=iris)
2012年

@Macro好答案(+1)!我想知道您是否可以拟合gls模型,但允许每个物种具有不同的剩余方差weights=varIdent(form=~1|Species)(关于第二个问题)?
COOLSerdash

15

要使用R代码回答这些问题,请使用以下命令:
1.如何测试斜率之间的差异?
答案:通过按物种进行的Petal.Width相互作用检查ANOVA p值,然后使用lsmeans :: lstrends比较斜率,如下所示。

library(lsmeans)
m.interaction <- lm(Sepal.Length ~ Petal.Width*Species, data = iris)
anova(m.interaction)
 Analysis of Variance Table

 Response: Sepal.Length
                      Df Sum Sq Mean Sq  F value Pr(>F)    
 Petal.Width           1 68.353  68.353 298.0784 <2e-16 ***
 Species               2  0.035   0.017   0.0754 0.9274    
 Petal.Width:Species   2  0.759   0.380   1.6552 0.1947    
 Residuals           144 33.021   0.229                    
 ---
 Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

# Obtain slopes
m.interaction$coefficients
m.lst <- lstrends(m.interaction, "Species", var="Petal.Width")
 Species    Petal.Width.trend        SE  df   lower.CL upper.CL
 setosa             0.9301727 0.6491360 144 -0.3528933 2.213239
 versicolor         1.4263647 0.3459350 144  0.7425981 2.110131
 virginica          0.6508306 0.2490791 144  0.1585071 1.143154

# Compare slopes
pairs(m.lst)
 contrast                 estimate        SE  df t.ratio p.value
 setosa - versicolor    -0.4961919 0.7355601 144  -0.675  0.7786
 setosa - virginica      0.2793421 0.6952826 144   0.402  0.9149
 versicolor - virginica  0.7755341 0.4262762 144   1.819  0.1669

2.如何测试残差之间的差异?
如果我理解这个问题,可以将Pearson相关性与Fisher变换(也称为“ Fisher的r至z”)进行比较,如下所示。

library(psych)
library(data.table)
iris <- as.data.table(iris)
# Calculate Pearson's R
m.correlations <- iris[, cor(Sepal.Length, Petal.Width), by = Species]
m.correlations
# Compare R values with Fisher's R to Z
paired.r(m.correlations[Species=="setosa", V1], m.correlations[Species=="versicolor", V1], 
         n = iris[Species %in% c("setosa", "versicolor"), .N])
paired.r(m.correlations[Species=="setosa", V1], m.correlations[Species=="virginica", V1], 
         n = iris[Species %in% c("setosa", "virginica"), .N])
paired.r(m.correlations[Species=="virginica", V1], m.correlations[Species=="versicolor", V1], 
         n = iris[Species %in% c("virginica", "versicolor"), .N])

3.介绍这些比较的一种简单有效的方法是什么?
“我们使用线性回归比较了每种物种的萼片长度与花瓣宽度之间的关系。对于I. Setosa(B = 0.9),I。Versicolor(B = 1.4),也不是维珍妮卡岛(B = 0.6); F(2,144)= 1.6,p = 0.19。Fisher的r-z-z比较表明,I。Setosa(r = 0.28)的皮尔逊相关系数为显着低于(I = Versicolor)(p = 0.02)(r = 0.55)。同样,I。Virginica(r = 0.28)的相关性也较I. Versicolor显着弱(p = 0.02)。”

最后,始终将结果可视化!

plotly_interaction <- function(data, x, y, category, colors = col2rgb(viridis(nlevels(as.factor(data[[category]])))), ...) {
  # Create Plotly scatter plot of x vs y, with separate lines for each level of the categorical variable. 
  # In other words, create an interaction scatter plot.
  # The "colors" must be supplied in a RGB triplet, as produced by col2rgb().

  require(plotly)
  require(viridis)
  require(broom)

  groups <- unique(data[[category]])

  p <- plot_ly(...)

  for (i in 1:length(groups)) {
    groupData = data[which(data[[category]]==groups[[i]]), ]
    p <- add_lines(p, data = groupData,
                   y = fitted(lm(data = groupData, groupData[[y]] ~ groupData[[x]])),
                   x = groupData[[x]],
                   line = list(color = paste('rgb', '(', paste(colors[, i], collapse = ", "), ')')),
                   name = groups[[i]],
                   showlegend = FALSE)
    p <- add_ribbons(p, data = augment(lm(data = groupData, groupData[[y]] ~ groupData[[x]])),
                     y = groupData[[y]],
                     x = groupData[[x]],
                     ymin = ~.fitted - 1.96 * .se.fit,
                     ymax = ~.fitted + 1.96 * .se.fit,
                     line = list(color = paste('rgba','(', paste(colors[, i], collapse = ", "), ', 0.05)')), 
                     fillcolor = paste('rgba', '(', paste(colors[, i], collapse = ", "), ', 0.1)'),
                     showlegend = FALSE)
    p <- add_markers(p, data = groupData, 
                     x = groupData[[x]], 
                     y = groupData[[y]],
                     symbol = groupData[[category]],
                     marker = list(color=paste('rgb','(', paste(colors[, i], collapse = ", "))))
  }
  p <- layout(p, xaxis = list(title = x), yaxis = list(title = y))
  return(p)
}

plotly_interaction(iris, "Sepal.Length", "Petal.Width", "Species")

虹膜图


8

我同意先前的建议。您应该为每个数据集拟合一个带有虚拟变量的多元回归模型。这将允许您测试截距是否不同。如果您还想知道斜率是否不同,则还需要包括虚拟变量和相关变量之间的相互作用。数据是独立的这一事实没有问题。请注意,如果它们既是独立的又是(例如)不同的物种,那么您将无法分辨出发现的差异是由于不同的物种还是由于不同的数据集而造成的,因为它们完全混淆了。但是,没有测试 /免除监狱卡,可以解决这个问题,而无需收集新样本并再次运行研究。


看起来我们几乎在同一时间发布了相当相似的答案。+1
Macro 2012年

@Macro,是的,但是您的大多数情况下都更好(更早地+1);您回答了我在第一次(不完全)阅读时遗漏的所有3个问题。我在这里所做的贡献是关于混淆的部分。
gung-恢复莫妮卡

是的,这是一个好点。我想如果您要进行全部查询,则必须假设数据集正在测量同一事物,等等……唯一的区别是物种不同。
2012年

3
从我的思维方式来看,你们两个都应该得到我的支持。
Michael R. Chernick

1
虚拟变量建议是一个很好的建议,前提是模型之间的误差差异不明显。 否则,您可以应用Satterthwaite-Welch t检验(具有唯一的优势,即只有已知的摘要统计信息时才可用,这在阅读已发表的论文时经常如此)或使用加权最小二乘拟合组合模型。
whuber
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.