为了将曲线拟合到一组点上,我们可以使用普通最小二乘回归
ordinary least-squares。MathWorks有一篇
solution page描述了这个过程。
例如,让我们从一些随机数据开始:
% some 3d points
data = mvnrnd([0 0 0], [1 -0.5 0.8
正如 @BasSwinckels 所示,通过构建所需的design matrix,您可以使用mldivide
或pinv
来解决表示为Ax=b
的超定系统:
C = [data(:,1) data(:,2) ones(size(data,1),1)] \ data(:,3);
[xx,yy] = meshgrid(-3:.5:3, -3:.5:3);
zz = C(1)*xx + C(2)*yy + C(3);
接下来我们将结果可视化:
figure('Renderer','opengl')
line(data(:,1), data(:,2), data(:,3), 'LineStyle','none', ...
'Marker','.', 'MarkerSize',25, 'Color','r')
surface(xx, yy, zz, ...
'FaceColor','interp', 'EdgeColor','b', 'FaceAlpha',0.2)
grid on; axis tight equal;
view(9,9);
xlabel x; ylabel y; zlabel z;
colormap(cool(64))
正如所提到的,我们可以通过向自变量矩阵(在Ax=b中的A)添加更多项来获得高阶多项式拟合。
假设我们想要拟合一个包含常数、线性、交互和平方项(1、x、y、xy、x^2、y^2)的二次模型。我们可以手动完成这个过程:
C = [ones(50,1) data(:,1:2) prod(data(:,1:2),2) data(:,1:2).^2] \ data(:,3);
zz = [ones(numel(xx),1) xx(:) yy(:) xx(:).*yy(:) xx(:).^2 yy(:).^2] * C;
zz = reshape(zz, size(xx));
统计工具箱中还有一个辅助函数x2fx
,可帮助构建几种模型阶数的设计矩阵:
C = x2fx(data(:,1:2), 'quadratic') \ data(:,3);
zz = x2fx([xx(:) yy(:)], 'quadratic') * C;
zz = reshape(zz, size(xx));
最后,在John D'Errico的文件交换中有一个优秀的函数polyfitn
,它允许您指定各种多项式阶数和涉及的项:
model = polyfitn(data(:,1:2), data(:,3), 2);
zz = polyvaln(model, [xx(:) yy(:)]);
zz = reshape(zz, size(xx));