matlab中具有季节性成分的最小二乘法

时间:2015-01-27 13:23:23

标签: matlab least-squares

我正在阅读一篇论文,该论文着眼于过去20年左右每月风速数据的调查趋势。本文使用了许多不同的统计方法,我试图在这里复制。

使用的第一种方法是形式

的简单线性回归模型

$$ y(t)= a_ {1} t + b_ {1} $$

其中$ a_ {1} $和$ b_ {1} $可以通过标准最小二乘法确定。

然后他们指出通过拟合表格模型来计算季节性信号,可以明确地消除线性回归模型中的一些潜在误差:

$$ y(t)= a_ {2} t + b_ {2} \ sin \ left(\ frac {2 \ pi} {12t} + c_ {2} \ right)+ d_ {2} $$

其中系数$ a_ {2} $,$ b_ {2} $,$ c_ {2} $和$ d_ {2} $可由最小二乘确定。然后,他们继续指出该模型还使用了3,4和6个月的额外谐波分量进行了测试。

以下列数据为例:

 %   1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
y = [112  115  145  171  196  204  242  284  315  340  360  417    % Jan
     118  126  150  180  196  188  233  277  301  318  342  391    % Feb
     132  141  178  193  236  235  267  317  356  362  406  419    % Mar
     129  135  163  181  235  227  269  313  348  348  396  461    % Apr
     121  125  172  183  229  234  270  318  355  363  420  472    % May
     135  149  178  218  243  264  315  374  422  435  472  535    % Jun
     148  170  199  230  264  302  364  413  465  491  548  622    % Jul
     148  170  199  242  272  293  347  405  467  505  559  606    % Aug
     136  158  184  209  237  259  312  355  404  404  463  508    % Sep
     119  133  162  191  211  229  274  306  347  359  407  461    % Oct
     104  114  146  172  180  203  237  271  305  310  362  390    % Nov
     118  140  166  194  201  229  278  306  336  337  405  432 ]; % Dec

time = datestr(datenum(yr(:),mo(:),1));
jday = datenum(time,'dd-mmm-yyyy');
y2 = reshape(y,[],1);

plot(jday,y2)

有谁可以证明上面的模型如何用matlab编写?

1 个答案:

答案 0 :(得分:2)

请注意,您的模型实际上是线性的,我们可以使用trigonometric identity来表示。要使用非线性模型,请使用nlinfit

使用您的数据我编写了以下脚本来计算和比较不同的方法:

(你可以注释掉opts.RobustWgtFun = 'bisquare';行,看它与12周期的线性拟合完全相同)

% y = [112  115 ...
y2 = reshape(y,[],1);
t=(1:144).';

% trend
T = [ones(size(t)) t];
B=T\y2;
y_trend = T*B;

% least squeare, using linear fit and the 12 periodicity only
T = [ones(size(t)) t sin(2*pi*t/12) cos(2*pi*t/12)];
B=T\y2;
y_sincos = T*B;

% least squeare, using linear fit and 3,4,6,12 periodicities
addharmonics = [3 4 6];
T = [T bsxfun(@(h,t)sin(2*pi*t/h),addharmonics,t) bsxfun(@(h,t)cos(2*pi*t/h),addharmonics,t)];
B=T\y2;
y_sincos2 = T*B;

% least squeare with bisquare weights, 
% using non-linear model of a linear fit and the 12 periodicity only
opts = statset('nlinfit');
opts.RobustWgtFun = 'bisquare';
b0 = [1;1;0;1];
modelfun = @(b,x) b(1)*x+b(2)*sin((b(3)+x)*2*pi/12)+b(4);
b = nlinfit(t,y2,modelfun,b0,opts);

% plot a comparison
figure
plot(t,y2,t,y_trend,t,modelfun(b,t),t,y_sincos,t,y_sincos2)
legend('Original','Trend','bisquare weight - 12 periodicity only', ...
    'least square - 12 periodicity only','least square - 3,4,6,12 periodicities', ...
    'Location','NorthWest');
xlim(minmax(t'));

Comparison of the fitted curves