このページは機械翻訳を使用して翻訳されました。元の英語を参照するには、ここをクリックします。
lsqcurvefit
または lsqnonlin
を使用したマルチスタート
この例では、lsqcurvefit
と MultiStart
を組み合わせて使用して、関数をデータに適合させる方法を示します。例の最後では、lsqnonlin
を使用した同じソリューションを示しています。
多くのフィッティング問題には複数のローカル ソリューションが存在します。MultiStart
は、最適なフィッティングを意味するグローバル ソリューションを見つけるのに役立ちます。この例では、便利な構文のため、まず lsqcurvefit
を使用します。
モデルは次のとおりです。
ここで、入力データは であり、パラメーター 、、、および は未知のモデル係数です。
手順 1: 目的関数を作成します。
N
行と 2 列のデータ マトリックス xdata
を受け取り、N
行の応答ベクトルを返す匿名関数を記述します。この関数は、係数ベクトル に対応する係数行列 p
も受け取ります。
fitfcn = @(p,xdata)p(1) + p(2)*xdata(:,1).*sin(p(3)*xdata(:,2)+p(4));
手順 2: トレーニングデータを作成します。
200 個のデータ ポイントと応答を作成します。値 を使用します。応答にランダムノイズを含めます。
rng default % For reproducibility N = 200; % Number of data points preal = [-3,1/4,1/2,1]; % Real coefficients xdata = 5*rand(N,2); % Data points ydata = fitfcn(preal,xdata) + 0.1*randn(N,1); % Response data with noise
手順 3: 境界と初期点を設定します。
lsqcurvefit
の境界を設定します。正弦関数は幅 の任意の区間にわたってその全範囲の値を取るため、 が絶対値で を超える理由はありません。高い周波数を許可すると応答が不安定になったり、収束が不正確になったりする可能性があるため、係数 の絶対値は 20 より小さくする必要があると想定します。
lb = [-Inf,-Inf,-20,-pi]; ub = [Inf,Inf,20,pi];
初期点を任意に(5,5,5,0)に設定します。
p0 = 5*ones(1,4); % Arbitrary initial point p0(4) = 0; % Ensure the initial point satisfies the bounds
手順 4: 最適なローカルフィットを見つけましょう。
p0
から始めて、パラメータをデータに適合させます。
[xfitted,errorfitted] = lsqcurvefit(fitfcn,p0,xdata,ydata,lb,ub)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
xfitted = 1×4
-2.6149 -0.0238 6.0191 -1.6998
errorfitted = 28.2524
lsqcurvefit
は、モデル パラメーター値 (–3,1/4,1/2,1) に特に近いわけではないローカル ソリューションを見つけます。
手順 5: MultiStart
の問題を設定します。
MultiStart
が同じ問題を解決できるように問題構造を作成します。
problem = createOptimProblem('lsqcurvefit','x0',p0,'objective',fitfcn,... 'lb',lb,'ub',ub,'xdata',xdata,'ydata',ydata);
手順 6.グローバルな解決策を見つけましょう。
MultiStart
を使用して 50 回の反復でフィッティング問題を解きます。最小誤差を MultiStart
反復回数としてプロットします。
ms = MultiStart('PlotFcns',@gsplotbestf);
[xmulti,errormulti] = run(ms,problem,50)
MultiStart completed the runs from all start points. All 50 local solver runs converged with a positive local solver exitflag.
xmulti = 1×4
-2.9852 -0.2472 -0.4968 -1.0438
errormulti = 1.6464
MultiStart
は、パラメータ値 (–3,–1/4,–1/2,–1) 付近のグローバル ソリューションを探します。(これは、preal
= (–3,1/4,1/2,1) 付近の解に相当します。最初の係数を除くすべての係数の符号を変更すると、fitfcn
と同じ数値が得られるためです。)残差誤差のノルムは約 28 から約 1.6 に減少し、10 倍以上の減少となります。
lsqnonlin
の問題を定式化する
別の方法として、フィッティング関数として lsqnonlin
を使用します。この場合、予測値と実際のデータ値の差を目的関数として使用します。
fitfcn2 = @(p)fitfcn(p,xdata)-ydata; [xlsqnonlin,errorlsqnonlin] = lsqnonlin(fitfcn2,p0,lb,ub)
Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
xlsqnonlin = 1×4
-2.6149 -0.0238 6.0191 -1.6998
errorlsqnonlin = 28.2524
同じ初期点 p0
から開始して、 lsqnonlin
は lsqcurvefit
と同じ比較的貧弱な解を見つけます。
lsqnonlin
をローカル ソルバーとして使用して MultiStart
を実行します。
problem2 = createOptimProblem('lsqnonlin','x0',p0,'objective',fitfcn2,... 'lb',lb,'ub',ub'); [xmultinonlin,errormultinonlin] = run(ms,problem2,50)
MultiStart completed the runs from all start points. All 50 local solver runs converged with a positive local solver exitflag.
xmultinonlin = 1×4
-2.9852 -0.2472 -0.4968 -1.0438
errormultinonlin = 1.6464
ここでも、MultiStart
はローカル ソルバーのみよりもはるかに優れたソリューションを見つけます。