このページは機械翻訳を使用して翻訳されました。最新版の英語を参照するには、ここをクリックします。
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. <stopping criteria details>
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 分の 1 以上減少しています。
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. <stopping criteria details>
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 はローカル ソルバーのみを使用する場合よりもはるかに優れたソリューションを見つけます。