反转计算已知移动平均值的原始数据

时间:2016-04-12 18:01:00

标签: matlab moving-average

我正在尝试估算计算(已知)移动平均线的(未知)原始数据点。但是,我确实知道原始数据点的一些,我不知道如何使用这些信息。

我正在使用答案中给出的方法:https://stats.stackexchange.com/questions/67907/extract-data-points-from-moving-average,但在MATLAB中(我的代码如下)。这种方法对于大量数据点(> 1000)非常有效,但对于较少的数据点则不太好,正如您所期望的那样。

window = 3;
datapoints = 150;
data = 3*rand(1,datapoints)+50;
moving_averages = [];
for i = window:size(data,2)
    moving_averages(i) = mean(data(i+1-window:i));
end

length = size(moving_averages,2)+(window-1);
a = (tril(ones(length,length),window-1) - tril(ones(length,length),-1))/window;
a = a(1:length-(window-1),:);
ai = pinv(a);

daily = mtimes(ai,moving_averages');

x = 1:size(data,2);
figure(1)
hold on
plot(x,data,'Color','b');
plot(x(window:end),moving_averages(window:end),'Linewidth',2,'Color','r');
plot(x,daily(window:end),'Color','g');
hold off
axis([0 size(x,2) min(daily(window:end))-1 max(daily(window:end))+1])
legend('original data','moving average','back-calculated')

现在,说我知道原始数据点的一小部分。我无法确定如何使用该信息来更准确地计算其余信息。感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

以下是same idea的示例:

% the actual vector of values
a = cumsum(rand(150,1) - 0.5);

% compute moving average
win = 3;  % sliding window length
idx = hankel(1:win, win:numel(a));
m = mean(a(idx));

% coefficient matrix: m(i) = sum(a(i:i+win-1))/win
A = repmat([ones(1,win) zeros(1,numel(a)-win)], numel(a)-win+1, 1);
for i=2:size(A,1)
    A(i,:) = circshift(A(i-1,:), [0 1]);
end
A = A / win;

% solve linear system
%x = A \ m(:);
x = pinv(A) * m(:);

% plot and compare
subplot(211), plot(1:numel(a),a, 1:numel(m),m)
legend({'original','moving average'})
title(sprintf('length = %d, window = %d',numel(a),win))
subplot(212), plot(1:numel(a),a, 1:numel(a),x)
legend({'original','reconstructed'})
title(sprintf('error = %f',norm(x(:)-a(:))))

result

您可以看到重建误差非常小,即使使用示例中的数据大小(150个样本具有3个样本移动平均值)。

答案 1 :(得分:0)

如果您在任何时候可以准确地确定一个窗口的数据量,即在这种情况下长度为n的窗口中的n-1个样本,您应该能够准确地计算原始数据。 (在你的情况下)如果你知道A,B和(A + B + C)/ 3,你现在可以解决并且知道C.现在当你有(B + C + D)/ 3(你的移动平均线)时你可以完全解决D.冲洗并重复。这种逻辑也是倒退的。