如何计算两个斜率的差异?

机器算法验证 r 回归 相互作用 线性模型
2022-03-04 21:58:45

有没有一种方法可以了解两条线是否(或多或少)平行?我有两条线由线性回归生成,我想了解它们是否平行。换句话说,我想得到这两条线的不同斜率。

有R函数来计算吗?

编辑: ......我怎样才能得到线性回归线的斜率(以度为单位)?

3个回答

我想知道我是否遗漏了一些明显的东西,但是您不能使用 ANCOVA 在统计上做到这一点吗?一个重要的问题是,两个回归中的斜率是错误估计它们是对整个人口斜率的估计。如果关注的是两条回归线在总体中以获得精确等价是没有意义的;它们都受到需要考虑的错误/不确定性的影响。a1a2

如果我们从统计的角度考虑这一点,我们可以以某种有意义的方式将两个数据集的来自两个具有相似范围的群体)变量只是它们之间的关系在两个总体中不同),那么我们可以拟合以下两个模型:xyxy

y^=b0+b1x+b2g

y^=b0+b1x+b2g+b3xg

其中是模型系数,是分组变量/因子,表示每个观测值属于哪个数据集。big

我们可以使用 ANOVA 表或 F 比来测试第二个更复杂的模型是否比更简单的模型更适合数据。更简单的模型表明两条线的斜率相同(),但两条线相互偏移了量。b1b2

更复杂的模型包括直线斜率和分组变量之间的交互作用。如果此交互项的系数显着不同于零,或者 ANOVA/F 比率表明更复杂的模型更好地拟合数据,那么我们必须拒绝两条线平行的空假设。

这是 R 中使用虚拟数据的示例。首先,具有相等斜率的数据:

set.seed(2)
samp <- factor(sample(rep(c("A","B"), each = 50)))
d1 <- data.frame(y = c(2,5)[as.numeric(samp)] + (0.5 * (1:100)) + rnorm(100),
                 x = 1:100,
                 g = samp)
m1 <- lm(y ~ x * g, data = d1)
m1.null <- lm(y ~ x + g, data = d1)
anova(m1.null, m1)

这使

> anova(m1.null, m1)
Analysis of Variance Table

Model 1: y ~ x + g
Model 2: y ~ x * g
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     97 122.29                           
2     96 122.13  1   0.15918 0.1251 0.7243

表明我们未能拒绝该数据样本中等斜率的原假设。当然,我们想向自己保证,如果确实存在差异,我们有足够的能力检测到差异,这样我们就不会因为我们的样本量太小而无法达到预期的效果而导致错误地拒绝无效。

现在有不同的坡度。

set.seed(42)
x <- seq(1, 100, by = 2)
d2 <- data.frame(y = c(2 + (0.5 * x) + rnorm(50),
                       5 + (1.5 * x) + rnorm(50)),
                 x = x,
                 g = rep(c("A","B"), each = 50))
m2 <- lm(y ~ x * g, data = d2)
m2.null <- lm(y ~ x + g, data = d2)
anova(m2.null, m2)

这使:

> anova(m2.null, m2)
Analysis of Variance Table

Model 1: y ~ x + g
Model 2: y ~ x * g
  Res.Df     RSS Df Sum of Sq     F    Pr(>F)    
1     97 21132.0                                 
2     96   103.8  1     21028 19439 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

在这里,我们有大量证据反对原假设,因此我们可以拒绝它而支持替代假设(换句话说,我们拒绝两条线的斜率相等的假设)。

我拟合的两个模型中的交互项 ( ) 给出了两组斜率的估计差异。对于第一个模型,斜率差异的估计值很小(~0.003)b3xg

> coef(m1)
(Intercept)           x          gB        x:gB 
2.100068977 0.500596394 2.659509181 0.002846393

并且对此进行检验将无法拒绝该斜率差异为 0 的零假设:t

> summary(m1)

Call:
lm(formula = y ~ x * g, data = d1)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.32886 -0.81224 -0.01569  0.93010  2.29984 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 2.100069   0.334669   6.275 1.01e-08 ***
x           0.500596   0.005256  95.249  < 2e-16 ***
gB          2.659509   0.461191   5.767 9.82e-08 ***
x:gB        0.002846   0.008047   0.354    0.724    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 1.128 on 96 degrees of freedom
Multiple R-squared: 0.9941, Adjusted R-squared: 0.9939 
F-statistic:  5347 on 3 and 96 DF,  p-value: < 2.2e-16 

如果我们转向适合第二个数据集的模型,我们使两组的斜率不同,我们看到两条线的斜率估计差异约为 1 个单位。

> coef(m2)
(Intercept)           x          gB        x:gB 
  2.3627432   0.4920317   2.8931074   1.0048653 

“A”组的斜率约为 0.49(x在上面的输出中),而要获得“B”组的斜率,我们需要将差异斜率(由交互项记住)添加到“A”组的斜率; ~0.49 + ~1 = ~1.49。这非常接近“B”组 1.5 的规定斜率。对这种斜率差异的检验还表明,差异的估计值远离 0:t

> summary(m2)

Call:
lm(formula = y ~ x * g, data = d2)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.1962 -0.5389  0.0373  0.6952  2.1072 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 2.362743   0.294220   8.031 2.45e-12 ***
x           0.492032   0.005096  96.547  < 2e-16 ***
gB          2.893107   0.416090   6.953 4.33e-10 ***
x:gB        1.004865   0.007207 139.424  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 1.04 on 96 degrees of freedom
Multiple R-squared: 0.9994, Adjusted R-squared: 0.9994 
F-statistic: 5.362e+04 on 3 and 96 DF,  p-value: < 2.2e-16

第一个问题实际上来自几何。如果您有两行表格:

y=a1x+b1
y=a2x+b2

则它们是平行的因此,如果斜率相等,则线是平行的。a1=a2

的事实,其中是直线与轴的夹角,是直线的斜率。所以tanα=a1αxa1

α=arctana1

并转换为度数,回想一下所以学位的答案将是2π=360

α=arctana13602π.

的 R 函数称为arctanatan

示例 R 代码:

> x<-rnorm(100)
> y<-x+1+rnorm(100)/2
> mod<-lm(y~x)
> mod$coef
    (Intercept)           x 
      0.9416175   0.9850303 
    > mod$coef[2]
        x 
0.9850303 
> atan(mod$coef[2])*360/2/pi
       x 
44.56792 

最后一行是度数。

更新。对于负斜率值转换为度数应遵循不同的规则。请注意,与 x 轴的角度可以得到从 0 到 180 的值,因为我们假设角度在 x 轴上方。的负值,公式为:a1

α=180arctana13602π.

笔记。虽然回忆高中三角学对我来说很有趣,但真正有用的答案是 Gavin Simpson 给出的答案。由于回归线的斜率是随机变量,因此应使用统计假设框架来比较它们。

... 跟进@mpiktas 的回答,这是从lm对象中提取斜率并应用上述公式的方法。

# prepare some data, see ?lm
ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2,10,20, labels=c("Ctl","Trt"))
weight <- c(ctl, trt)

lm.D9 <- lm(weight ~ group)
# extract the slope (this is also used to draw a regression line if you wrote abline(lm.D9)
coefficients(lm.D9)["groupTrt"] 
      groupTrt 
   -0.371 
# use the arctan*a1 / (360 / (2*pi)) formula provided by mpiktas
atan(coefficients(lm.D9)["groupTrt"]) * (360/(2 * pi)) 
 groupTrt 
-20.35485 
180-atan(coefficients(lm.D9)["groupTrt"]) * (360/(2 * pi))
 groupTrt 
200.3549