线性回归拟合不好

机器算法验证 r 回归
2022-03-20 21:51:28

我使用 R lm 函数进行线性回归:

x = log(errors)
plot(x,y)
lm.result = lm(formula = y ~ x)
abline(lm.result, col="blue") # showing the "fit" in blue

在此处输入图像描述

但它不太适合。不幸的是,我无法理解手册。

有人可以指出我正确的方向以更好地适应这个吗?

通过拟合我的意思是我想最小化均方根误差(RMSE)。


编辑:我在这里发布了一个相关的问题(这是同样的问题): 我可以根据这个功能进一步降低 RMSE 吗?

和这里的原始数据:

http://tny.cz/c320180d

除了那个链接上的 x 是这里当前页面上所谓的错误,并且样本较少(当前页面图中的 1000 对 3000)。我想在另一个问题中使事情变得更简单。

4个回答

最简单的解决方案之一是认识到概率之间的小变化(如 0.1)或补码小的概率(如 0.9)通常比中等概率(如 0.5)之间的变化更有意义,并且应该得到更多的权重。

例如,从 0.1 变为 0.2 (a) 使概率加倍,而 (b) 仅将互补概率改变 1/9(将其从 1-0.1 = 0.9 降至 1-0.2 至 0.8),而从 0.5 变为到 0.6 (a) 仅将概率增加 20%,而 (b) 仅将互补概率降低 20%。在许多应用程序中,第一个变化被认为或至少应该被认为几乎是第二个变化的两倍。

在任何情况下,如果使用(某事发生的)概率或其补语(即某事不发生的概率)同样有意义,我们应该尊重这种对称性。

这两个想法——尊重概率和它们的补码之间的对称性,以及相对而不是绝对地表达变化——建议在比较两个概率时,我们应该同时跟踪它们的比率和它们的补码的比率 在跟踪比率时,使用对数更简单,它将比率转换为差异。 因此,为此目的的一个好方法这被称为对数赔率logitp1pppp/p(1p)/(1p)p

z=logplog(1p),
拟合对数几率总是可以通过反转 logit 转换回概率; 下面代码的最后一行显示了这是如何完成的。pz
p=exp(z)/(1+exp(z)).

这个推理相当笼统:它导致了一个很好的默认初始过程,用于探索任何涉及概率的数据集。(有更好的方法可用,例如泊松回归,当概率基于观察“成功”与“试验”数量的比率时,因为基于更多试验的概率被更可靠地测量。这似乎不是此处的情况,其中概率基于导出的信息。可以通过在下面的示例中使用加权最小二乘法来近似泊松回归方法,以允许或多或少可靠的数据。)

让我们看一个例子。

数据

左侧的散点图显示了一个以对数赔率绘制的数据集(类似于问题中的那个)。红线是它的普通最小二乘拟合。它具有较低的,表明大量分散和强烈的“均值回归”:回归线的斜率小于此椭圆点云的长轴。这是一个熟悉的环境;使用's函数或等效函数很容易解释和分析。R2Rlm

右侧的散点图以概率的形式表示数据,因为它们最初是记录的。绘制了相同的拟合:由于对数几率转换为概率的非线性方式,现在它看起来是弯曲的。

就对数几率的均方根误差而言,这条曲线是最佳拟合。

顺便说一句,左侧云的近似椭圆形状以及它跟踪最小二乘线的方式表明最小二乘回归模型是合理的:数据可以用线性关系充分描述——只要使用对数几率——无论水平位置如何(同方差),线周围的垂直变化大小大致相同。(中间有一些异常低的值可能值得仔细检查。)通过使用以下命令plot(fit)查看一些标准诊断来更详细地评估这一点。这本身就是使用对数赔率而不是概率来分析这些数据的一个强有力的理由。


#
# Read the data from a table of (X,Y) = (X, probability) pairs.
#
x <- read.table("F:/temp/data.csv", sep=",", col.names=c("X", "Y"))
#
# Define functions to convert between probabilities `p` and log odds `z`.
# (When some probabilities actually equal 0 or 1, a tiny adjustment--given by a positive
# value of `e`--needs to be applied to avoid infinite log odds.)
#
logit <- function(p, e=0) {x <- (p-1/2)*(1-e) + 1/2; log(x) - log(1-x)}
logistic <- function(z, e=0) {y <- exp(z)/(1 + exp(z)); (y-1/2)/(1-e) + 1/2}
#
# Fit the log odds using least squares.
#
b <- coef(fit <- lm(logit(x$Y) ~ x$X))
#
# Plot the results in two ways.
#
par(mfrow=c(1,2))
plot(x$X, logit(x$Y), cex=0.5, col="Gray",
     main="Least Squares Fit", xlab="X", ylab="Log odds")
abline(b, col="Red", lwd=2)

plot(x$X, x$Y, cex=0.5, col="Gray",
     main="LS Fit Re-expressed", xlab="X", ylab="Probability")
curve(logistic(b[1] + b[2]*x), col="Red", lwd=2, add=TRUE)

考虑到 x 的数据偏斜,显而易见的第一件事就是使用逻辑回归(wiki 链接)。所以我同意这个。我会说x其本身将显示出强烈的意义,但不能解释大部分偏差(相当于 OLS 中的总平方和)。所以有人可能会建议除了x有助于解释力(例如进行分类的人或使用的方法),您的y数据已经 [0,1] 了:你知道它们是代表概率还是发生率?如果是这样,您应该尝试使用未转换的逻辑回归y(在它们是比率/概率之前)。

只有当您的 y 不是概率时,Peter Flom 的观察才有意义。检查plot(density(y));rug(y)不同的桶x看看你是否看到了变化的 Beta 发行版或只是运行betareg. 请注意,beta 分布也是指数族分布,因此应该可以glm在 R 中对其进行建模。

为了让您了解我所说的逻辑回归的含义:

# the 'real' relationship where y is interpreted as the probability of success
y = runif(400)
x = -2*(log(y/(1-y)) - 2) + rnorm(400,sd=2) 
glm.logit=glm(y~x,family=binomial); summary(glm.logit) 
plot(y ~ x); require(faraway); grid()
points(x,ilogit(coef(glm.logit) %*% rbind(1.0,x)),col="red")
tt=runif(400)  # an example of your untransformed regression
newy = ifelse(tt < y, 1, 0)
glm.logit=glm(newy~x,family=binomial); summary(glm.logit) 

# if there is not a good match in your tail probabilities try different link function or oversampling with correction (will be worse here, but perhaps not in your data)
glm.probit=glm(y~x,family=binomial(link=probit)); summary(glm.probit)
glm.cloglog=glm(y~x,family=binomial(link=cloglog)); summary(glm.cloglog)

真实模型为 $log(\frac{p}{1-p})=2-0.5x 的逻辑回归

编辑:阅读评论后:

鉴于“y 值是某个类别的概率,是从人们手动完成的平均分类中获得的”,我强烈建议对您的基础数据进行逻辑回归。这是一个例子:

假设您正在查看某人同意提案的概率(y=1同意,y=0不同意)给予激励x介于 0 和 10 之间(可以进行对数转换,例如报酬)。有两个人向候选人提出要约(“吉尔和杰克”)。真正的模型是候选人有一个基本的接受率,并且随着激励的增加而增加。但这也取决于谁提出了这个提议(在这种情况下,我们说吉尔比杰克有更好的机会)。假设他们询问 1000 名候选人并收集他们的接受 (1) 或拒绝 (0) 数据。

require(faraway)
people = c("Jill","Jack")
proposer = sample(people,1000,replace=T)
incentive = runif(1000, min = 0, max =10)
noise = rnorm(1000,sd=2)
# base probability of agreeing is about 12% (ilogit(-2))
agrees = ilogit(-2 + 1*incentive + ifelse(proposer == "Jill", 0 , -0.75) + noise) 
tt = runif(1000)
observedAgrees = ifelse(tt < agrees,1,0)
glm.logit=glm(observedAgrees~incentive+proposer,family=binomial); summary(glm.logit) 

从摘要中您可以看到该模型非常适合。偏差是χn32(标准χ22.df)。哪个适合并且它以固定概率击败模型(偏差差异为数百χ22)。考虑到这里有两个协变量,绘制起来有点困难,但你明白了。

xs = coef(glm.logit) %*% rbind(1,incentive,as.factor(proposer))
ys = as.vector(unlist(ilogit(xs)))
plot(ys~ incentive, type="n"); require(faraway); grid()
points(incentive[proposer == "Jill"],ys[proposer == "Jill"],col="red")
points(incentive[proposer == "Jack"],ys[proposer == "Jack"],col="blue")

吉尔穿红色杰克蓝色

正如你所看到的,吉尔比杰克更容易获得良好的命中率,但随着激励的增加,这种情况就会消失。

您基本上应该将这种类型的模型应用于您的原始数据。如果您的输出是二进制的,如果是多项式,则保留 1/0,您需要多项式逻辑回归。如果您认为额外的方差来源不是数据收集器,请添加另一个您认为对您的数据有意义的因素(或连续变量)。数据排在第一位、第二位和第三位,然后模型才发挥作用。

线性回归模型不太适合数据。人们可能期望从回归中得到类似以下内容:

在此处输入图像描述

但是通过了解 OLS 的作用,很明显这不是您将得到的。普通最小二乘法的图形解释是它最小化线(超平面)和数据之间的平方垂直距离。显然我叠加的紫色线有一些巨大的残差x(7,4.5)再次在 3 的另一侧。这就是为什么蓝线比紫线更适合的原因。

由于 Y 以 0 和 1 为界,普通的最小二乘回归并不适合。你可以试试 beta 回归。R里面有包裹betareg

尝试这样的事情

install.packages("betareg")
library(betareg)
betamod1 <- betareg(y~x, data = DATASETNAME)

更多信息

编辑:如果您想全面了解 beta 回归及其优缺点,请参阅更好的柠檬挤压器: Smithson 和 Verkuilen 的具有 beta 分布因变量的最大似然回归