如果解释变量和响应变量在回归之前独立排序会发生什么?

机器算法验证 回归 相关性
2022-01-18 10:19:37

假设我们有 n 个点的数据集(我们想要执行线性回归,但首先我们将值和值相互独立地排序,形成数据集对新数据集的回归是否有任何有意义的解释?这个有名字吗?(Xi,Yi)nXiYi(Xi,Yj)

我想这是一个愚蠢的问题,所以我很抱歉,我没有接受过正式的统计培训。在我看来,这完全破坏了我们的数据,回归毫无意义。但是我的经理说,当他这样做时,他“大多数时候都会得到更好的回归”(这里“更好”意味着更具预测性)。我有一种感觉,他在欺骗自己。

编辑:谢谢你所有的好和耐心的例子。我向他展示了@RUser4512 和@gung 的例子,他仍然很坚定。他变得烦躁,我变得筋疲力尽。我感到沮丧。我可能很快就会开始寻找其他工作。

4个回答

我不确定你的老板认为“更具预测性”是什么意思。许多人错误地认为较低值意味着更好/更具预测性的模型。 这不一定是正确的(这是一个恰当的例子)。但是,预先对两个变量进行独立排序将保证较低的值。另一方面,我们可以通过将模型的预测与同一过程生成的新数据进行比较来评估模型的预测准确性。我在下面的一个简单示例中执行此操作(使用 编码)。 ppR

options(digits=3)                       # for cleaner output
set.seed(9149)                          # this makes the example exactly reproducible

B1 = .3
N  = 50                                 # 50 data
x  = rnorm(N, mean=0, sd=1)             # standard normal X
y  = 0 + B1*x + rnorm(N, mean=0, sd=1)  # cor(x, y) = .31
sx = sort(x)                            # sorted independently
sy = sort(y)
cor(x,y)    # [1] 0.309
cor(sx,sy)  # [1] 0.993

model.u = lm(y~x)
model.s = lm(sy~sx)
summary(model.u)$coefficients
#             Estimate Std. Error t value Pr(>|t|)
# (Intercept)    0.021      0.139   0.151    0.881
# x              0.340      0.151   2.251    0.029  # significant
summary(model.s)$coefficients
#             Estimate Std. Error t value Pr(>|t|)
# (Intercept)    0.162     0.0168    9.68 7.37e-13
# sx             1.094     0.0183   59.86 9.31e-47  # wildly significant

u.error = vector(length=N)              # these will hold the output
s.error = vector(length=N)
for(i in 1:N){
  new.x      = rnorm(1, mean=0, sd=1)   # data generated in exactly the same way
  new.y      = 0 + B1*x + rnorm(N, mean=0, sd=1)
  pred.u     = predict(model.u, newdata=data.frame(x=new.x))
  pred.s     = predict(model.s, newdata=data.frame(x=new.x))
  u.error[i] = abs(pred.u-new.y)        # these are the absolute values of
  s.error[i] = abs(pred.s-new.y)        #  the predictive errors
};  rm(i, new.x, new.y, pred.u, pred.s)
u.s = u.error-s.error                   # negative values means the original
                                        # yielded more accurate predictions
mean(u.error)  # [1] 1.1
mean(s.error)  # [1] 1.98
mean(u.s<0)    # [1] 0.68


windows()
  layout(matrix(1:4, nrow=2, byrow=TRUE))
  plot(x, y,   main="Original data")
  abline(model.u, col="blue")
  plot(sx, sy, main="Sorted data")
  abline(model.s, col="red")
  h.u = hist(u.error, breaks=10, plot=FALSE)
  h.s = hist(s.error, breaks=9,  plot=FALSE)
  plot(h.u, xlim=c(0,5), ylim=c(0,11), main="Histogram of prediction errors",
       xlab="Magnitude of prediction error", col=rgb(0,0,1,1/2))
  plot(h.s, col=rgb(1,0,0,1/4), add=TRUE)
  legend("topright", legend=c("original","sorted"), pch=15, 
         col=c(rgb(0,0,1,1/2),rgb(1,0,0,1/4)))
  dotchart(u.s, color=ifelse(u.s<0, "blue", "red"), lcolor="white",
           main="Difference between predictive errors")
  abline(v=0, col="gray")
  legend("topright", legend=c("u better", "s better"), pch=1, col=c("blue","red"))

在此处输入图像描述

左上图显示了原始数据。之间存在某种关系(即,相关性约为。)右上图显示了对两个变量进行独立排序后数据的样子。您可以很容易地看到相关性的强度大幅增加(现在约为)。然而,在下面的图中,我们看到在原始(未排序)数据上训练的模型的预测误差分布更接近于使用原始数据的模型的平均绝对预测误差为,而在排序数据上训练的模型的平均绝对预测误差为xy.31.9901.11.98——几乎是原来的两倍。这意味着排序数据模型的预测与正确值相去甚远。右下象限的图是点图。它显示预测误差与原始数据和排序数据之间的差异。这使您可以比较每个模拟的新观察的两个相应预测。左侧的蓝点是原始数据更接近新值的时间,右侧的红点是排序数据产生更好预测的时间。的时间里 ,在原始数据上训练的模型有更准确的预测。y68%


排序导致这些问题的程度取决于数据中存在的线性关系。如果之间的相关性已经为,则排序将无效,因此不会有害。另一方面,如果相关性为xy1.01.0,排序将完全颠倒关系,使模型尽可能不准确。如果数据最初完全不相关,则排序将对结果模型的预测准确性产生中间但仍然相当大的有害影响。既然你提到你的数据通常是相关的,我怀疑这已经提供了一些保护来防止这个过程固有的危害。尽管如此,先排序肯定是有害的。为了探索这些可能性,我们可以简单地用不同的值重新运行上面的代码B1(使用相同的种子来重现性)并检查输出:

  1. B1 = -5

    cor(x,y)                            # [1] -0.978
    summary(model.u)$coefficients[2,4]  # [1]  1.6e-34  # (i.e., the p-value)
    summary(model.s)$coefficients[2,4]  # [1]  1.82e-42
    mean(u.error)                       # [1]  7.27
    mean(s.error)                       # [1] 15.4
    mean(u.s<0)                         # [1]  0.98
    
  2. B1 = 0

    cor(x,y)                            # [1] 0.0385
    summary(model.u)$coefficients[2,4]  # [1] 0.791
    summary(model.s)$coefficients[2,4]  # [1] 4.42e-36
    mean(u.error)                       # [1] 0.908
    mean(s.error)                       # [1] 2.12
    mean(u.s<0)                         # [1] 0.82
    
  3. B1 = 5

    cor(x,y)                            # [1] 0.979
    summary(model.u)$coefficients[2,4]  # [1] 7.62e-35
    summary(model.s)$coefficients[2,4]  # [1] 3e-49
    mean(u.error)                       # [1] 7.55
    mean(s.error)                       # [1] 6.33
    mean(u.s<0)                         # [1] 0.44
    

如果你想说服你的老板,你可以用模拟的、随机的、独立的数据来展示正在发生的事情。使用 R:x,y在此处输入图像描述

n <- 1000

y<- runif(n)
x <- runif(n)

linearModel <- lm(y ~ x)


x_sorted <- sort(x)
y_sorted <- sort(y)

linearModel_sorted <- lm(y_sorted ~ x_sorted)

par(mfrow = c(2,1))
plot(x,y, main = "Random data")
abline(linearModel,col = "red")


plot(x_sorted,y_sorted, main = "Random, sorted data")
abline(linearModel_sorted,col = "red")

显然,排序后的结果提供了更好的回归。但是,鉴于用于生成数据的过程(两个独立样本),绝对不可能使用其中一个来预测另一个。

您的直觉是正确的:独立排序的数据没有可靠的含义,因为输入和输出是随机映射到彼此的,而不是观察到的关系。

排序数据的回归很有可能看起来不错,但在上下文中没有意义。

直观的例子:假设一个数据集(X=age,Y=height)对于某些人群。纯粹数据的图表可能看起来更像是一个对数或幂函数:儿童的生长速度较快,而后来的青少年生长速度较慢,并且“渐近”地接近年轻人和老年人的最大身高。

如果我们排序x,y按升序排列,图形可能几乎是线性的。因此,预测功能是人们终其一生都长得更高。我不会在那个预测算法上赌钱。

实际上,让我们让它变得非常明显和简单。假设我进行了一个实验,在标准容器中量出 1 升水,然后查看容器中剩余的水量Vi作为时间的函数ti,因蒸发而失水:

现在假设我获得以下测量值(ti,Vi)分别以小时和升为单位:

(0,1.0),(1,0.9),(2,0.8),(3,0.7),(4,0.6),(5,0.5).
这显然是完全相关的(和假设的)数据。但是如果我要对时间和体积测量进行排序,我会得到
(0,0.5),(1,0.6),(2,0.7),(3,0.8),(4,0.9),(5,1.0).
并且从这个排序后的数据集得出的结论是,随着时间的增加,水的体积会增加,而且,从 1 升水开始,等待 5 小时后,你会得到超过 1 升的水。这不是很了不起吗?这个结论不仅与原始数据所说的相反,还表明我们发现了新的物理学!