如果我有一些(x,y)数据,我可以很容易地直线绘制,例如
f=glm(y~x)
plot(x,y)
lines(x,f$fitted.values)
Run Code Online (Sandbox Code Playgroud)
但对于弯曲的数据,我想要一条曲线.似乎可以使用loess():
f=loess(y~x)
plot(x,y)
lines(x,f$fitted)
Run Code Online (Sandbox Code Playgroud)
这个问题随着我输入和研究而得到了发展.我开始想要一个简单的函数来适应弯曲的数据(我对数据一无所知),并想要了解如何使用nls()或optim()做到这一点.这就是每个人似乎在我发现的类似问题中提出的建议.但现在我偶然发现loess()我很高兴.所以,现在我的问题是为什么有人会选择使用nls或optim代替loess(或smooth.spline)?使用工具箱类比,是nls一把螺丝刀,loess是一个电动螺丝刀(意思是我几乎总是选择后者,因为它做同样的事情,但我的努力更少)?或者是nls平头螺丝刀和loess十字螺丝刀(意味着黄土更适合某些问题,但对于其他人来说它根本不能完成这项工作)?
作为参考,这里是我正在使用的播放数据,它loess给出了令人满意的结果:
x=1:40
y=(sin(x/5)*3)+runif(x)
Run Code Online (Sandbox Code Playgroud)
和:
x=1:40
y=exp(jitter(x,factor=30)^0.5)
Run Code Online (Sandbox Code Playgroud)
可悲的是,它在这方面做得不太好:
x=1:400
y=(sin(x/20)*3)+runif(x)
Run Code Online (Sandbox Code Playgroud)
nls()或任何其他函数或库,可以处理这个和前面的exp示例,而不给出提示(即没有被告知它是正弦波)?
更新:stackoverflow上相同主题的一些有用页面:
smooth.spline"开箱即用"在我的第一和第三个例子上给出了很好的结果,但在第二个例子中可怕(它只是加入了点).然而,f = smooth.spline(x,y,spar = 0.5)在所有三个上都是好的.
更新#2:gam()(来自mgcv包)到目前为止很棒:当它更好时它会给loess()一个类似的结果,而当它更好时它会给smooth.spline()一个类似的结果.并且没有提示或额外参数.到目前为止,文件已经超出了我的脑海,我觉得我正眯着眼睛望着飞过头顶的飞机; 但发现了一些试验和错误:
#f=gam(y~x) #Works just like glm(). I.e. pointless
f=gam(y~s(x)) #This is what you want
plot(x,y)
lines(x,f$fitted)
Run Code Online (Sandbox Code Playgroud)
Rei*_*son 25
非线性最小二乘法是一种拟合参数非线性模型的方法.通过拟合模型,我的意思是对于响应和协变量之间的关系存在一些先验指定的形式,其中一些未知参数将被估计.由于模型在这些参数中是非线性的,因此NLS是通过以迭代方式最小化最小二乘准则来估计那些系数的值的手段.
LOESS是作为平滑散点图的一种手段而开发的.它有一个非常不明确的"模型"概念(IIRC没有"模型").LOESS的工作原理是尝试识别响应和协变量之间关系中的模式,而无需用户指定该关系的形式.LOESS从数据本身中解决了这种关系.
这是两个根本不同的想法.如果您知道数据应该遵循特定模型,那么您应该使用NLS来适应该模型.您可以随时比较两个拟合(NLS与LOESS)以查看是否存在来自假定模型的系统变化等 - 但这将显示在NLS残差中.
您可以考虑通过gam()推荐的软件包mgcv中安装的广义附加模型(GAM),而不是LOESS .这些模型可以看作是一个惩罚性的回归问题,但允许从数据中估算拟合的平滑函数,就像它们在黄土中一样.GAM扩展了GLM以允许协变量的平滑,任意函数.