Нахождение лучшей точки на кривой компромисса

Скажите, что у меня были некоторые данные, для которых я хочу соответствовать параметрической модели по нему. Моя цель состоит в том, чтобы найти оптимальное значение для этого параметра модели.

Я делаю образцовый выбор с помощью AIC/BIC/MDL типа критерия, который вознаграждает модели низкой ошибкой, но также и штрафует модели с высокой сложностью (мы ищем самое простое все же самое убедительное объяснение этих данных если можно так выразиться, а-ля бритва Оккама).

После вышеупомянутого это - пример вида вещей, которые я получаю для трех различных критериев (два, должны быть минимизированы, и один, чтобы быть максимизированным):

aic-bicfit

Визуально можно легко видеть форму колена, и Вы выбрали бы значение для параметра где-нибудь в том регионе. Проблема состоит в том, что я делаю, делают это для большого количества экспериментов, и мне нужен способ найти это значение без вмешательства.

Моя первая интуиция состояла в том, чтобы попытаться остановиться перед углом на 45 градусов от угла, и продолжать движение это до него пересекает кривую, но это легче сказать чем сделать :) Также это может пропустить видимую область, если кривая несколько скашивается.

Какие-либо мысли о том, как реализовать это или лучшие идеи?

Вот образцы, должен был воспроизвести один из графиков выше:

curve = [8.4663 8.3457 5.4507 5.3275 4.8305 4.7895 4.6889 4.6833 4.6819 4.6542 4.6501 4.6287 4.6162 4.585 4.5535 4.5134 4.474 4.4089 4.3797 4.3494 4.3268 4.3218 4.3206 4.3206 4.3203 4.2975 4.2864 4.2821 4.2544 4.2288 4.2281 4.2265 4.2226 4.2206 4.2146 4.2144 4.2114 4.1923 4.19 4.1894 4.1785 4.178 4.1694 4.1694 4.1694 4.1556 4.1498 4.1498 4.1357 4.1222 4.1222 4.1217 4.1192 4.1178 4.1139 4.1135 4.1125 4.1035 4.1025 4.1023 4.0971 4.0969 4.0915 4.0915 4.0914 4.0836 4.0804 4.0803 4.0722 4.065 4.065 4.0649 4.0644 4.0637 4.0616 4.0616 4.061 4.0572 4.0563 4.056 4.0545 4.0545 4.0522 4.0519 4.0514 4.0484 4.0467 4.0463 4.0422 4.0392 4.0388 4.0385 4.0385 4.0383 4.038 4.0379 4.0375 4.0364 4.0353 4.0344];
plot(1:100, curve)

Править

Я принял решение, данное Jonas. В основном, для каждой точки p на кривой мы находим ту с максимальным расстоянием d данный:

point-line-distance

47
задан Community 23 May 2017 в 11:33
поделиться

4 ответа

Быстрый способ найти локоть - это провести линию от первой до последней точки кривой, а затем найти точку данных, наиболее удаленную от этой линии.

Это, конечно, несколько зависит от количества точек на плоской части линии, но если каждый раз проверять одно и то же количество параметров, то все должно получиться достаточно хорошо.

curve = [8.4663 8.3457 5.4507 5.3275 4.8305 4.7895 4.6889 4.6833 4.6819 4.6542 4.6501 4.6287 4.6162 4.585 4.5535 4.5134 4.474 4.4089 4.3797 4.3494 4.3268 4.3218 4.3206 4.3206 4.3203 4.2975 4.2864 4.2821 4.2544 4.2288 4.2281 4.2265 4.2226 4.2206 4.2146 4.2144 4.2114 4.1923 4.19 4.1894 4.1785 4.178 4.1694 4.1694 4.1694 4.1556 4.1498 4.1498 4.1357 4.1222 4.1222 4.1217 4.1192 4.1178 4.1139 4.1135 4.1125 4.1035 4.1025 4.1023 4.0971 4.0969 4.0915 4.0915 4.0914 4.0836 4.0804 4.0803 4.0722 4.065 4.065 4.0649 4.0644 4.0637 4.0616 4.0616 4.061 4.0572 4.0563 4.056 4.0545 4.0545 4.0522 4.0519 4.0514 4.0484 4.0467 4.0463 4.0422 4.0392 4.0388 4.0385 4.0385 4.0383 4.038 4.0379 4.0375 4.0364 4.0353 4.0344];

%# get coordinates of all the points
nPoints = length(curve);
allCoord = [1:nPoints;curve]';              %'# SO formatting

%# pull out first point
firstPoint = allCoord(1,:);

%# get vector between first and last point - this is the line
lineVec = allCoord(end,:) - firstPoint;

%# normalize the line vector
lineVecN = lineVec / sqrt(sum(lineVec.^2));

%# find the distance from each point to the line:
%# vector between all points and first point
vecFromFirst = bsxfun(@minus, allCoord, firstPoint);

%# To calculate the distance to the line, we split vecFromFirst into two 
%# components, one that is parallel to the line and one that is perpendicular 
%# Then, we take the norm of the part that is perpendicular to the line and 
%# get the distance.
%# We find the vector parallel to the line by projecting vecFromFirst onto 
%# the line. The perpendicular vector is vecFromFirst - vecFromFirstParallel
%# We project vecFromFirst by taking the scalar product of the vector with 
%# the unit vector that points in the direction of the line (this gives us 
%# the length of the projection of vecFromFirst onto the line). If we 
%# multiply the scalar product by the unit vector, we have vecFromFirstParallel
scalarProduct = dot(vecFromFirst, repmat(lineVecN,nPoints,1), 2);
vecFromFirstParallel = scalarProduct * lineVecN;
vecToLine = vecFromFirst - vecFromFirstParallel;

%# distance to line is the norm of vecToLine
distToLine = sqrt(sum(vecToLine.^2,2));

%# plot the distance to the line
figure('Name','distance from curve to line'), plot(distToLine)

%# now all you need is to find the maximum
[maxDist,idxOfBestPoint] = max(distToLine);

%# plot
figure, plot(curve)
hold on
plot(allCoord(idxOfBestPoint,1), allCoord(idxOfBestPoint,2), 'or')
41
ответ дан 26 November 2019 в 19:38
поделиться

Смысл выбора информационно-теоретической модели состоит в том, что она уже учитывает количество параметров. Поэтому нет необходимости искать локоть, нужно только найти минимум.

Поиск локтя кривой имеет значение только при использовании подгонки. Даже тогда метод, который вы выбираете для выбора локтя, в каком-то смысле устанавливает штраф за количество параметров. Для выбора локтя необходимо минимизировать расстояние от начала до кривой. Относительное взвешивание двух измерений при расчете расстояния создаст свой собственный штрафной балл. Информационно-теоретический критерий задает эту метрику на основе количества параметров и количества выборок данных, используемых для оценки модели.

Bottom line recommendation: Используйте BIC и возьмите минимум.

.
8
ответ дан 26 November 2019 в 19:38
поделиться

Таким образом, одним из способов решения этой проблемы было бы подогнать две линии к L локтя. Но так как в одном участке кривой есть только несколько точек (как я уже упоминал в комментарии), то подгонка прямых принимает удар, если только вы не определите, какие точки находятся на расстоянии друг от друга и не интерполируете между ними для создания более однородного ряда и , то использует RANSAC для нахождения двух прямых, подходящих к L - немного извилистых, но не невозможных.

Так что вот более простое решение - построенные Вами графики выглядят именно так, как они выглядят благодаря масштабированию MATLAB (очевидно). Так что все, что я сделал, это минимизировал расстояние от "начала" до Ваших точек с помощью информации о масштабе.

Обратите внимание: Оценка начала может быть значительно улучшена, но я оставлю это на Ваше усмотрение.

Вот код:

%% Order
curve = [8.4663 8.3457 5.4507 5.3275 4.8305 4.7895 4.6889 4.6833 4.6819 4.6542 4.6501 4.6287 4.6162 4.585 4.5535 4.5134 4.474 4.4089 4.3797 4.3494 4.3268 4.3218 4.3206 4.3206 4.3203 4.2975 4.2864 4.2821 4.2544 4.2288 4.2281 4.2265 4.2226 4.2206 4.2146 4.2144 4.2114 4.1923 4.19 4.1894 4.1785 4.178 4.1694 4.1694 4.1694 4.1556 4.1498 4.1498 4.1357 4.1222 4.1222 4.1217 4.1192 4.1178 4.1139 4.1135 4.1125 4.1035 4.1025 4.1023 4.0971 4.0969 4.0915 4.0915 4.0914 4.0836 4.0804 4.0803 4.0722 4.065 4.065 4.0649 4.0644 4.0637 4.0616 4.0616 4.061 4.0572 4.0563 4.056 4.0545 4.0545 4.0522 4.0519 4.0514 4.0484 4.0467 4.0463 4.0422 4.0392 4.0388 4.0385 4.0385 4.0383 4.038 4.0379 4.0375 4.0364 4.0353 4.0344];
x_axis = 1:numel(curve);
points = [x_axis ; curve ]'; %' - SO formatting

%% Get the scaling info
f = figure(1);
plot(points(:,1),points(:,2));
ticks = get(get(f,'CurrentAxes'),'YTickLabel');
ticks = str2num(ticks);
aspect = get(get(f,'CurrentAxes'),'DataAspectRatio');
aspect = [aspect(2) aspect(1)];    
close(f);   

%% Get the "origin"
O = [x_axis(1) ticks(1)];

%% Scale the data - now the scaled values look like MATLAB''s idea of
% what a good plot should look like
scaled_O = O.*aspect;
scaled_points = bsxfun(@times,points,aspect);

%% Find the closest point
del = sum((bsxfun(@minus,scaled_points,scaled_O).^2),2);
[val ind] = min(del);
best_ROC = [ind curve(ind)];

%% Display
plot(x_axis,curve,'.-');
hold on;
plot(O(1),O(2),'r*');
plot(best_ROC(1),best_ROC(2),'k*');

Результаты:

results

ALSO для кривой Fit(maximum) Вы должны будете изменить начало отсчета на [x_axis(1) ticks(end)].

.
5
ответ дан 26 November 2019 в 19:38
поделиться

Во-первых, быстрый просмотр вычислений: первая производная f' каждого графика представляет собой скорость, при которой изменяется функция f, на которой выполняется граффити. Вторая производная f'' представляет собой курс, на котором изменяется f'. Если f'' маленький, это означает, что график меняет направление со скромным темпом. Но если f'' большой, это означает, что график быстро меняет направление.

Хочется выделить точки, в которых f'' наибольший размер над областью графика. Это будут точки-кандидаты на выбор оптимальной модели. Какая точка должна быть выбрана вами, так как вы не указали точно, насколько вы цените фитнес в сравнении со сложностью.

7
ответ дан 26 November 2019 в 19:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: