将正弦项拟合到数据

机器算法验证 r 回归 配件
2022-01-26 04:57:07

虽然我读了这篇文章,但我仍然不知道如何将它应用到我自己的数据中,希望有人能帮助我。

我有以下数据:

y <- c(11.622967, 12.006081, 11.760928, 12.246830, 12.052126, 12.346154, 12.039262, 12.362163, 12.009269, 11.260743, 10.950483, 10.522091,  9.346292,  7.014578,  6.981853,  7.197708,  7.035624,  6.785289, 7.134426,  8.338514,  8.723832, 10.276473, 10.602792, 11.031908, 11.364901, 11.687638, 11.947783, 12.228909, 11.918379, 12.343574, 12.046851, 12.316508, 12.147746, 12.136446, 11.744371,  8.317413, 8.790837, 10.139807,  7.019035,  7.541484,  7.199672,  9.090377,  7.532161,  8.156842,  9.329572, 9.991522, 10.036448, 10.797905)
t <- 18:65

现在我只想拟合一个正弦波

y(t)=Asin(ωt+ϕ)+C.

有四个未知数AωϕC

我的其余代码如下所示

res <- nls(y ~ A*sin(omega*t+phi)+C, data=data.frame(t,y), start=list(A=1,omega=1,phi=1,C=1))
co <- coef(res)

fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d}

# Plot result
plot(x=t, y=y)
curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE ,lwd=2, col="steelblue")

但是结果真的很差。

正弦拟合

我将非常感谢任何帮助。

干杯。

4个回答

如果你只是想要一个好的估计而不太关心它的标准误差:ω

ssp <- spectrum(y)  
per <- 1/ssp$freq[ssp$spec==max(ssp$spec)]
reslm <- lm(y ~ sin(2*pi/per*t)+cos(2*pi/per*t))
summary(reslm)

rg <- diff(range(y))
plot(y~t,ylim=c(min(y)-0.1*rg,max(y)+0.1*rg))
lines(fitted(reslm)~t,col=4,lty=2)   # dashed blue line is sin fit

# including 2nd harmonic really improves the fit
reslm2 <- lm(y ~ sin(2*pi/per*t)+cos(2*pi/per*t)+sin(4*pi/per*t)+cos(4*pi/per*t))
summary(reslm2)
lines(fitted(reslm2)~t,col=3)    # solid green line is periodic with second harmonic

正弦图

(更好的拟合可能仍会以某种方式解释该系列中的异常值,从而减少它们的影响。)

---

如果您想了解中的不确定性,可以使用轮廓似然性(pdf1pdf2 - 从轮廓似然性或其变体中获取近似 CI 或 SE 的参考并不难找到)ω

(或者,您可以将这些估计输入 nls ...并开始它已经收敛。)

正如@Stefan 所建议的那样,不同的起始值似乎确实可以显着提高拟合度。我观察数据表明 omega 应该约为,因为这些峰值看起来相距约 20 个单位。2π/20

当我把它放到nls'sstart列表中时,我得到了一条更合理的曲线,尽管它仍然存在一些系统性偏差。

根据您使用此数据集的目标,您可以尝试通过添加附加项或使用非参数方法(如具有周期性内核的高斯过程)来改进拟合。

正弦拟合

自动选择起始值

如果要选择主频率,可以使用快速傅里叶变换 (FFT)。这超出了我的专业领域,所以如果其他人愿意,我会让他们填写详细信息(尤其是关于步骤 2 和 3),但R下面的代码应该可以工作。

# Step 1: do the FFT
raw.fft = fft(y)

# Step 2: drop anything past the N/2 - 1th element.
# This has something to do with the Nyquist-shannon limit, I believe
# (https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem)
truncated.fft = raw.fft[seq(1, length(y)/2 - 1)]

# Step 3: drop the first element. It doesn't contain frequency information.
truncated.fft[1] = 0

# Step 4: the importance of each frequency corresponds to the absolute value of the FFT.
# The 2, pi, and length(y) ensure that omega is on the correct scale relative to t.
# Here, I set omega based on the largest value using which.max().
omega = which.max(abs(truncated.fft)) * 2 * pi / length(y)

您还可以绘图abs(truncated.fft)以查看是否还有其他重要频率,但您必须稍微调整 x 轴的缩放比例。

另外,我相信@Glen_b 是正确的,一旦您知道 omega(或者您也需要知道 phi?我不确定),问题就是凸的。在任何情况下,如果它们在正确的范围内,知道其他参数的起始值不应该像 omega 那样重要。您可能可以从 FFT 中获得对其他参数的不错估计,但我不确定它是如何工作的。

作为已经说过的替代方案,值得注意的是,ARIMA 模型类中的 AR(2) 模型可用于生成具有正弦波模式的预测。

AR(2) 模型可以写成: 其中是一个常数, ,是要估计的参数,是一个随机冲击项。

yt=C+ϕ1yt1+ϕ2yt2+at
Cϕ1ϕ2at

现在,并非所有 AR(2) 模型在其预测中都会产生正弦波模式(也称为随机周期),但当满足以下条件时,它确实会发生:

ϕ12+4ϕ2<0.

Panratz(1991) 告诉我们以下关于随机周期的内容:

随机周期模式可以被认为是预测模式中的扭曲正弦波模式:它是具有随机(概率)周期、幅度和相位角的正弦波。

为了查看这样的模型是否可以适合数据,我使用了auto.arima()预测包中的函数来确定它是否会建议 AR(2) 模型。事实证明,该auto.arima()函数建议使用 ARMA(2,2) 模型;不是纯 AR(2) 模型,但这没关系。没关系,因为 ARMA(2,2) 模型包含 AR(2) 组件,因此适用相同的规则(关于随机周期)。也就是说,我们仍然可以检查上述条件,看看是否会产生正弦波预测。

结果auto.arima(y)如下所示。

Series: y 
ARIMA(2,0,2) with non-zero mean 

Coefficients:
         ar1      ar2      ma1     ma2  intercept
      1.7347  -0.8324  -1.2474  0.6918    10.2727
s.e.  0.1078   0.0981   0.1167  0.1911     0.5324

sigma^2 estimated as 0.6756:  log likelihood=-60.14
AIC=132.27   AICc=134.32   BIC=143.5

现在让我们检查条件: 并且我们发现条件确实是满足的。

ϕ12+4ϕ2<01.73472+4(0.8324)<00.3202914<0

下图显示了原始序列 y、ARMA(2,2) 模型的拟合以及 14 个样本外预测。可以看出,样本外预测遵循正弦波模式。

在此处输入图像描述

请记住两件事。1)这只是一个非常快速的分析(使用自动化工具),适当的处理将涉及遵循 Box-Jenkins 方法。2)ARIMA 预测擅长短期预测,因此您可能会发现来自@David J. Harris 和@Glen_b 答案中的模型的长期预测更可靠。

最后,希望这是对一些已经非常有用的答案的一个很好的补充。

参考:使用动态回归模型进行预测:Alan Pankratz,1991,(John Wiley and Sons,纽约),ISBN 0-471-61528-5

当前将 sin 曲线拟合到给定数据集的方法需要首先猜测参数,然后是一个交互过程。这是一个非线性回归问题。由于方便的积分方程,另一种方法包括将非线性回归转换为线性回归。然后,不需要初始猜测,不需要迭代过程:直接获得拟合。如果函数 y = a + r*sin(w*x+phi) 或 y=a+b*sin(w*x)+c*cos(w*x),请参见论文的第 35-36 页《回归正弦曲线》发表在 Scribd 上: http ://www.scribd.com/JJacquelin/documents 在函数 y = a + p*x + r*sin(w*x+phi) 的情况下:“混合线性和正弦回归”一章的第 49-51 页。对于更复杂的函数,一般过程在“广义正弦回归”第 54-61 页一章中进行了说明,然后是一个数值示例 y = r*sin(w*x+phi)+(b/x)+c *ln(x),第 62-63 页