【问题标题】:Linear / Non-Linear Fit to a Sine Curve线性/非线性拟合正弦曲线
【发布时间】:2013-01-07 13:33:10
【问题描述】:

我看过thisthis

但我有一个稍微不同的问题。我知道我的数据是一条正弦曲线,具有未知周期和未知幅度,具有加性非高斯分布噪声。

我正在尝试使用 C 中的GSL 非线性算法对其进行拟合,但拟合效果非常糟糕。我想知道我是否(错误地)使用了非线性拟合算法,而我应该使用线性拟合算法?

如何判断特定数据集需要线性算法还是非线性算法?

编辑:我的曲线真的嘈杂,所以用 FFT 来计算频率可能会导致误报和不合适的结果。我正在寻找一种更稳健的拟合方式。

如您所见,上图有大约 170 个点,下图有大约 790 个点。

噪声明显是非高斯的,并且与数据的幅度相比很大。我已经在高斯分布的噪声上尝试过 FFT,我的配合非常好。在这里,它的失败非常严重。

添加:链接到first 时间序列数据。文件中的每一列都是不同的时间序列。

【问题讨论】:

  • 你能发个10000分吗。我只有 88 个。
  • @Kitchi:您发布的每个时间序列只有 86 分,这几乎肯定是不够的。您能否仅发布几个时间序列(2-3),每个时间序列有 1000 个或更多数据点?如果可能的话,10000 会更好。
  • “我知道我的数据 [有] ... 加性高斯分布噪声”或“噪声明显非高斯”——是什么?
  • @j_random_hacker - 抱歉,已编辑以解决该问题。

标签: c algorithm curve-fitting


【解决方案1】:

如果您知道您的数据是正弦曲线(可以表示为多个复指数),那么您可以使用 Pisarkenko 的调和分解; http://en.wikipedia.org/wiki/Pisarenko_harmonic_decomposition

但是,如果您可以访问更多数据点,我的方法仍然是使用 DFT。

更新:

我对您的数据使用了 Pisarenko 的谐波分解 (PHD),即使您的信号非常短(每个信号只有 86 个数据点),如果有更多可用数据,PHD 算法肯定具有潜力。下面包括 24 个信号中的两个(数据的第 11 和 13 列),用蓝色表示,红色的正弦曲线对应于 PHD 的估计幅度/频率值。 (注意相移是未知的)

我使用 MATLAB (pisar.m) 进行 PHD:http://www.mathworks.com/matlabcentral/fileexchange/74

% assume data is one single sine curve (in noise)
SIN_NUM = 1; 

for DATA_COLUMN = 1:24
    % obtain amplitude (A), and frequency (f = w/2*pi) estimate
    [A f]=pisar(data(:,DATA_COLUMN),SIN_NUM);

    % recreated signal from A, f estimate
    t = 0:length(data(:,DATA_COLUMN))-1;
    y = A*cos(2*pi*f*t);

    % plot original/recreated signal
    figure; plot(data(:,DATA_COLUMN)); hold on; plot(y,'r')
    title({'data column ',num2str(DATA_COLUMN)});

    disp(A)
    disp(f)
end

导致

1.9727     % amp. for  column 11
0.1323     % freq. for column 11
2.3231     % amp. for  column 13
0.1641     % freq. for column 13

博士验证:

我还进行了另一项测试,我知道幅度和频率的值,然后添加噪声以查看 PHD 是否可以从噪声信号中正确估计值。该信号由两条添加的正弦曲线组成,频率分别为 50 Hz、120 Hz,幅度分别为 0.7、1.0。下图中,红色曲线是原始曲线,蓝色曲线是添加了噪点的曲线。 (图被裁剪)

Fs = 1000; % Sampling frequency
T = 1/Fs; % Sample time
L = 1000; % Length of signal
t = (0:L-1)*T; % Time vector

% Sum of a 50 Hz sinusoid and a 120 Hz sinusoid
x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
y = x + 0.4*randn(size(t)); % Sinusoids plus noise

figure;
plot(Fs*t(1:100),y(1:100)); hold on; plot(Fs*t(1:100),x(1:100),'r')
title('Signal Corrupted with Zero-Mean Random Noise (Blue), Original (Red)')

[A, f] = pisar(y',2); 
disp(A)
disp(f/Fs)

PHD 估计的 amp/freq 值为:

0.7493    % amp wave 1  (actual 0.7)
0.9257    % amp wave 2  (actual 1.0)
58.5      % freq wave 1 (actual 50)
123.8     % freq wave 2 (actual 120)

对于相当多的噪音来说还不错,而且只知道信号包含的波数。

回复@Alex:

是的,这是一个很好的算法,我在 DSP 研究期间遇到了它,我认为它工作得很好,但重要的是要注意 Pisarenko 的 Harm.Dec。将任何信号建模为 N > 0 正弦曲线,从一开始就指定 N,并使用该值来忽略噪声。因此,根据定义,它仅在您大致了解数据由多少人正弦波组成时才有用。如果您不知道 N 的值,并且需要针对一千个不同的值运行算法,那么绝对推荐使用不同的方法。也就是说,此后评估很简单,因为它返回 N 个幅度和频率值。

多信号分类 (MUSIC) 是另一种算法,在 Pisarenko 停止的地方继续。 http://en.wikipedia.org/wiki/Multiple_signal_classification

【讨论】:

  • 太好了,我不知道这种方法。是否有任何进一步的工作或扩展?
  • 这太壮观了!显然这是对最大熵方法的改进?我还没有尝试过......但你的结果真的很好。谢谢!
  • 嗨基奇!我很高兴能帮上忙。是的,MEM 绝对可以用于频谱估计(它对很多事情都非常有用),但我相信它假设生成数据的随机过程(你想找到一个模型)是具有零均值的高斯性质。
【解决方案2】:

Kitchi:你能提供一些样本数据吗?您必须使用的典型信号多长时间? (根据样本数和正弦波周期数)信噪比是多少dB?

  1. 在你知道什么算法会起作用之前,我建议你在 python/numpy/scipy(或 matlab/octave,或 R/S,或 Mathematica...)中创建原型,无论你最喜欢什么原型语言/工具集,而不是 C。它将节省大量时间,并且您将使用更丰富的工具。

  2. 您确定噪声会严重影响 FFT 吗?这不一定是一个好的假设,特别是如果噪声相对“白”,并且分析窗口很长。如果正弦波的频率非常稳定,你可以做一个巨大的 FFT 并将信号从比信号强几个数量级的噪声中提取出来。尝试大约几百到几百万个周期的预期正弦波。

  3. 曲线拟合正弦波效果不佳。我猜周期性会产生很多局部最小值,而相移变量也会使问题显着非线性。您可以从下面链接的遇到相同问题的其他人那里看到一些问题。你最好尝试几乎任何其他东西而不是非线性最小二乘拟合,除非你对问题进行预线性化,这让我...

  4. 自相关非常适合这种事情。尝试一次计算整个信号的自相关(如果源频率稳定,数据越多越好)。正弦波周期作为自相关中的一个高峰应该非常明显,并且您可能会比使用 FFT 获得更准确的频率估计(除非您使用非常大的 FFT)。此外,您可以从第一个高自相关峰的高度计算平均幅度。

编辑:经过进一步研究,有更多的技术可能比 FFT 更适合您的问题。 Pisarenko 的调和分解(下面 Fredrik Rubin 首次提出)是一个;另一个是Least squares spectral analysis (LSSA),它与您最初的问题想法非常相似。 LSSA 有许多变体,例如 Lomb-Scargle、基础追踪等,它们以各种方式处理我上面描述的拟合问题。但是我认为,如果您绝对无法在大型 FFT 中看到任何信号,那么其他任何方法都不太可能找到任何东西 :)

附:有关无法很好地拟合正弦波的其他问题,请参阅:

【讨论】:

  • 我已经用我的数据的屏幕截图编辑了我的问题......正如我所展示的,长度可能是可变的。我正在考虑转向 python,因为它更容易进行实验。我会尝试自相关,看看它是否有效,谢谢!
  • @Kitchi:如果你想让我尝试任何东西,你能上传一个样本数据集吗? (文本或 csv 文件)我感兴趣的主要内容是一,源频率有多稳定,二,你想要适应一个完整的数据集多长时间(更长是 much更好,我建议您感兴趣信号周期的数千到数百万倍)。您的噪声显然有点偏向高频,并且比您的信号强很多,所以我认为除非您拥有大量数据集和稳定的源频率,否则任何技术都不会很好地工作。
  • 我现在不在有数据的机器上,我会在今天晚些时候处理它。当我这样做时,我会将您链接到这两个数据集。样本大小可能是信号周期的几倍到几百倍,但不幸的是,不会比这大多少。这就是问题出现的地方。
  • pastebin 会发布数据吗?哪里有上传的好地方?
【解决方案3】:

这实际上是一个频谱估计问题。您正在尝试估计一个“线谱”,您知道您拥有的正弦波数量(在您的情况下是一个)。 MUSICESPRIT 之类的方法应该可以解决问题。

供参考,Stoica 的书会派上用场。本书的第 4 章是线谱的参数方法,其中包含用于查找所需信号的幅度、相位和频率的算法。本书还附带algorithms implemented in MATLAB,也很容易自己实现。

【讨论】:

    【解决方案4】:

    如果您要对 sin 进行回归,您可以使用 FFT 应用傅里叶变换。

    编辑

    尝试使用过滤器去除噪音。如果您有传感器等物理源,请在传感器上放置低通滤波器。 FFT 是相对较差的过滤器。

    EDIT2 - 这个测量是完全错误的

    可能是您进行了错误的测量。根据Nyquist–Shannon sampling theorem 你的采样频率太低,或者输入频率太高。这会导致错误的解决方案,因为如果您使用 5kHz 采样进行采样,例如 3kHz,您将根据该定理测量 2kHz。

    我确信您无法通过这种测量来判断正确的输入频率。

    【讨论】:

    • 过滤器不好?如何?由于您可以将任何给定大小的过滤器实现为 fft + 卷积 + 逆 fft,因此预过滤完全没有优势。
    • FFT 不是过滤的最佳选择,可以通过一些数学分析看出。我不记得所有细节,但使用 FIR 甚至 IIR 滤波器进行滤波可以得到更好的结果。 FFT 的“问题”是它具有一阶极点,而 IIR 滤波器具有更高阶极点,因此在截止频率后衰减更好,
    • 你怎么知道你是,通过应用一个过滤器(任何类型的)不过滤掉你想检测的信号?换句话说;由于信号的性质未知,如何选择滤波器的截止频率?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2021-05-08
    • 1970-01-01
    • 2021-07-23
    • 2017-09-15
    • 2017-12-17
    相关资源
    最近更新 更多