MultiStart Использование lsqcurvefit или lsqnonlin

Этот пример показывает аппроксимацию функции к данным с помощью lsqcurvefit совместно с MultiStart. В конце примера показано то же решение с использованием lsqnonlin.

Многие аппроксимации имеют несколько локальных решений. MultiStart может помочь найти глобальное решение, означающее лучшую подгонку. Этот пример сначала использует lsqcurvefit из-за его удобного синтаксиса.

Модель является

y=a+bx1sin(cx2+d),

где входные данные x=(x1,x2), и параметры a, b, c, и d являются неизвестными коэффициентами модели.

Шаг 1. Создайте целевую функцию.

Написание анонимной функции, которая принимает матрицу данных xdata с N строки и два столбца, и возвращает вектор отклика с N строки. Функция также принимает матрицу коэффициентов p, соответствующий вектору коэффициента (a,b,c,d).

fitfcn = @(p,xdata)p(1) + p(2)*xdata(:,1).*sin(p(3)*xdata(:,2)+p(4));

Шаг 2. Создайте обучающие данные.

Создайте 200 точек данных и ответов. Используйте значения a=-3,b=1/4,c=1/2,d=1. Включите случайный шум в ответ.

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. Нет никаких причин для d превысить π в абсолютном значении, потому что функция синуса принимает значения во всей области значений на любом интервале ширины 2π. Примите, что коэффициент c должно быть меньше 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)

Figure MultiStart contains an axes. The axes with title Best Function Value: 1.6464 contains 2 objects of type line, text.

MultiStart completed the runs from all start points.

All 50 local solver runs converged with a positive local solver exit flag.
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.

Выполняйте MultiStart использование lsqnonlin как локальный решатель.

problem2 = createOptimProblem('lsqnonlin','x0',p0,'objective',fitfcn2,...
    'lb',lb,'ub',ub');
[xmultinonlin,errormultinonlin] = run(ms,problem2,50)

Figure MultiStart contains an axes. The axes with title Best Function Value: 1.6464 contains 2 objects of type line, text.

MultiStart completed the runs from all start points.

All 50 local solver runs converged with a positive local solver exit flag.
xmultinonlin = 1×4

   -2.9852   -0.2472   -0.4968   -1.0438

errormultinonlin = 1.6464

Снова, MultiStart находит намного лучшее решение, чем только локальный решатель.

Похожие темы