exponenta event banner

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

Связанные темы