a,b
ポイントとそれに対応するc
値の離散的な通常グリッドがあり、スムーズな曲線を得るためにさらに補間します。次に、補間データから、カーブフィッティング用の多項式を作成します。 3Dプロットを多項式にフィットさせる方法は?
私はこれをMATLABでやろうとしています。 3次元データをカーブフィットするために、MATLAB(r2010a)のサーフェスフィッティングツールボックスを使用しました。しかし、MATLAB/MAPLEまたはその他のソフトウェアで最高の利点を得るために、一連のデータに適合する式をどのように見つけますか。何かアドバイス?また、PDFファイル、Web上など)で確認する実際のコード例も最も役立ちます。
これは私のデータのほんの一部です。
a = [ 0.001 .. 0.011];
b = [1, .. 10];
c = [ -.304860225, .. .379710865];
前もって感謝します。
一連の点に曲線をフィットさせるには、 通常の最小二乗 回帰を使用できます。プロセスを説明するMathWorksの ソリューションページ があります。
例として、ランダムデータから始めましょう。
% some 3d points
data = mvnrnd([0 0 0], [1 -0.5 0.8; -0.5 1.1 0; 0.8 0 1], 50);
@ BasSwinckels が示すように、目的の 設計行列 を作成することにより、 mldivide
または pinv
to overdetermined systemを解決するAx=b
として表現:
% best-fit plane
C = [data(:,1) data(:,2) ones(size(data,1),1)] \ data(:,3); % coefficients
% evaluate it on a regular grid covering the domain of the data
[xx,yy] = meshgrid(-3:.5:3, -3:.5:3);
zz = C(1)*xx + C(2)*yy + C(3);
% or expressed using matrix/vector product
%zz = reshape([xx(:) yy(:) ones(numel(xx),1)] * C, size(xx));
次に、結果を視覚化します。
% plot points and surface
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
)に項を追加することで、より高次の多項式フィッティングを取得できます。
定数、線形、交互作用、2乗項(1、x、y、xy、x ^ 2、y ^ 2)を持つ2次モデルを近似したいとします。これは手動で行うことができます:
% best-fit quadratic curve
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));
また、Statistics Toolboxには、いくつかのモデル次数の計画行列の作成に役立つヘルパー関数 x2fx
があります。
C = x2fx(data(:,1:2), 'quadratic') \ data(:,3);
zz = x2fx([xx(:) yy(:)], 'quadratic') * C;
zz = reshape(zz, size(xx));
最後に、John D'ErricoによるFile Exchangeには優れた関数 polyfitn
があり、関係するすべての種類の多項式次数と項を指定できます。
model = polyfitn(data(:,1:2), data(:,3), 2);
zz = polyvaln(model, [xx(:) yy(:)]);
zz = reshape(zz, size(xx));
ファイル交換にはいくつかの優れた機能があるかもしれませんが、手動で行う1つの方法は次のとおりです。
x = a(:); %make column vectors
y = b(:);
z = c(:);
%first order fit
M = [ones(size(x)), x, y];
k1 = M\z;
%least square solution of z = M * k1, so z = k1(1) + k1(2) * x + k1(3) * y
同様に、2次近似を実行できます。
%second order fit
M = [ones(size(x)), x, y, x.^2, x.*y, y.^2];
k2 = M\z;
あなたが与えた限られたデータセットに対して数値的な問題があるようです。タイプhelp mldivide
詳細については。
通常のグリッド上で補間を行うには、次のようにします。
ngrid = 20;
[A,B] = meshgrid(linspace(min(a), max(a), ngrid), ...
linspace(min(b), max(b), ngrid));
M = [ones(numel(A),1), A(:), B(:), A(:).^2, A(:).*B(:), B(:).^2];
C2_fit = reshape(M * k2, size(A)); % = k2(1) + k2(2)*A + k2(3)*B + k2(4)*A.^2 + ...
%plot to compare fit with original data
surfl(A,B,C2_fit);shading flat;colormap gray
hold on
plot3(a,b,c, '.r')
3次の近似は、以下のTryHardによって与えられる式を使用して行うことができますが、次数が増加すると、式はすぐに面倒になります。 M
、x
、y
を指定して、order
を作成できる関数を作成する必要がある場合は、それを作成することをお勧めします。
これは、具体的な実装、特にビットに対して、哲学的な質問のように聞こえます。「データのセットに最も適した式をどのようにして見つけるのですか?」私の経験ではchoiceは、達成しようとしていることに応じて作成する必要があります。
あなたにとって「最高」を定義するものは何ですか?データフィッティングの問題については、多項式係数を追加していき、R ^ 2値を改善することができますが、最終的にはデータが「オーバーフィット」されます。高次多項式の欠点は、応答曲面を適合させるために使用したサンプルデータの範囲外の動作です-モデリングしようとしているものに適さない可能性がある、いくつかのワイルドな方向にすぐに外れる可能性があります。 。
適合しているシステム/データの物理的な動作について洞察がありますか?これは、数学モデルの作成に使用する方程式のセットの基礎として使用できます。私がお勧めするのは、最も経済的な(単純な)モデルを使用することです。