线性回归最佳多项式(或更好的使用方法)?

机器算法验证 回归 非线性回归 曲线拟合
2022-03-26 12:05:53

关于我可以成功用于应用回归的其他多项式的任何想法?我的目标是一个严格根据噪声拟合误差的解决方案。这是可能的,因为它是一个钟形曲线?尾巴可以长、短或不存在。我在寻找不可能的事吗?请注意,自从我深入线性回归以来已经有一段时间了。

无论如何,我的数据点不适合ax+bx2+c多项式足够好。我想替换这个多项式以应用回归(或不同的方法)。在以下示例中,每个点都错过了拟合曲线20%Y平均范围(数据点)。我查看了样条曲线,但我不知道如何应用回归,因为它们看起来是分段的。

例子Y值(均匀分布在X)。它看起来有点像钟形曲线。我将应用 5 到 50 个数据点来确定多项式系数。最终,我对最好的感兴趣X基于数据点的峰值位​​置。

 X      Y
-40    -21142.1111111111
-30    -21330.1111111111
-20    -12036.1111111111
-10      7255.3888888889
  0     32474.8888888889
 10     32474.8888888889
 20      9060.8888888889
 30    -11628.1111111111
 40    -15129.6111111111
3个回答

因为亮度是具有独立随机误差的响应,并且根据高斯函数预计会随着与最佳点的距离而逐渐减小,所以快速非线性回归应该做得很好。

模型是

y=b+aexp(12(xms)2)+ε

在哪里ε表示测量亮度的误差,这里建模为随机量。峰值出现在m;s>0量化曲线逐渐变细的速率;a>0反映相对的整体大小y价值观,以及b是基线。

让我们用示例数据(使用R)来尝试一下。通过包括中间 (m) 在这些参数中,软件会自动输出它的估计值和一个标准误差:

y <- c(-190279, -191971, -108325, 65298, 292274, 292274, 81548, -104653, -136166)/9
x <- (-4:4)*10
#
# Define a Gaussian function (of four parameters).
f <- function(x, theta)  { 
  m <- theta[1]; s <- theta[2]; a <- theta[3]; b <- theta[4];
  a*exp(-0.5*((x-m)/s)^2) + b
}
#
# Estimate some starting values.
m.0 <- x[which.max(y)]; s.0 <- (max(x)-min(x))/4; b.0 <- min(y); a.0 <- (max(y)-min(y))
#
# Do the fit.  (It takes no time at all.)
fit <- nls(y ~ f(x,c(m,s,a,b)), data.frame(x,y), start=list(m=m.0, s=s.0, a=a.0, b=b.0))
#
# Display the estimated location of the peak and its SE.
summary(fit)$parameters["m", 1:2]

非线性拟合的棘手部分通常是为参数找到好的起始值:此代码显示了一种(粗略的)方法。它的输出,

  Estimate Std. Error 
 5.3161940  0.4303487 

给出峰值的估计值 (5.32) 及其标准误 (0.43)。绘制拟合并将其与数据进行比较总是一个好主意:

par(mfrow=c(1,1))
plot(c(x,0),c(y,f(coef(fit)["m"],coef(fit))), main="Data", type="n",
     xlab="x", ylab="Brightness")
curve(f(x, coef(fit)), add=TRUE, col="Red", lwd=2)
points(x,y, pch=19)

数据与拟合

这正是我们所期望的:数据似乎非常适合高斯分布。为了更深入地了解拟合,绘制残差:

plot(x, resid(fit), main="Residuals")

残差图

您想检查大多数残差是否与亮度测量中的(已知?)变化一样小,并且其中没有重要的趋势或模式。我们可能有点担心高残差x=40,但在删除最后一个数据点的情况下重新运行该过程不会明显改变m(现在是5.25标准误为0.17,与之前的估计没有区别)。新的残差上下反弹,随着x变大,但在其他方面往往小于1000绝对值左右:这里没有迹象表明需要更多的努力来确定m.

我假设您提供的值列对应于某种时间序列,并且有一个隐含的“时间”列,其中包含您没有提到的均匀间隔的值。

鉴于此,如果您打算拟合多项式曲线进行预测或预测,问题仍然存在。如果是前者,那么可以使用自适应基础和交叉验证来确定最佳断点,从而实现样条的使用。样条曲线估计分段多项式趋势,具体取决于您指定的多项式次数(和断点数)。

另一方面,预测并不保证使用带有断点的样条曲线,因为如果您观察到数据,则无法将趋势外推到下一个断点所在的位置之外。

无论哪种情况,您是否确定R2使用具有独立数据集的外部验证的价值?如果是这样,那么您是如何选择 80% 的变异来确定适当的预测模型的?在我看来,这似乎是任意的,并且您更有可能通过这样做来适应噪音而几乎没有泛化。

如果您的数据应该是钟形曲线,您应该拟合它而不是问题中的二次曲线。但是,您可以使用“其他多项式”,例如在 Python 中使用 numpy.polyfit 的均方误差最小化:

import numpy as np
import pylab as pl
# generate bell curve data
X = np.sort((10 * np.random.rand(50, 1)-5), axis=0)
y = ((np.exp(-(X**2)/2))/(2*np.pi)).ravel()
# add some noise
y[::5] += (0.1 * np.random.rand(len(y)/5))
x = X.ravel()
# do the fit with 4 inflections and get the coefficients
z = np.polyfit(x,y,4)
# get a callable 
p = np.poly1d(z)
# plot
hf = pl.figure()
ax = hf.add_subplot(1,1,1)
xlab = xrange(0,len(x))
ax.scatter(x, y, c='k', label='data')
ax.plot(X,p(X), c='g', label='fit')
ax.set_xticklabels(xlab)
ax.set_xlabel('time')
ax.set_ylabel('brightness')
ax.set_title('Polyfit')
ax.legend()
pl.show()

输出:

在此处输入图像描述