найти строку, которая лучше всего соответствует данным

Я пытаюсь найти строку, которая лучше всего соответствует данным. Я использую следующий код ниже, но теперь я хочу, чтобы данные были помещены в массив, отсортированный так, чтобы сначала были данные, которые находятся ближе всего к строке, как я могу это сделать? Также полифит правильная функция использовать для этого?

x=[1,2,2.5,4,5];
y=[1,-1,-.9,-2,1.5];
n=1;
p = polyfit(x,y,n)

f = polyval(p,x);
plot(x,y,'o',x,f,'-')

Изображение

PS: я использую Octave 4.0, который похож на Matlab.


person Rick T    schedule 28.02.2017    source источник


Ответы (3)


Сначала вы можете вычислить ошибку между реальным значением y и прогнозируемым значением f.

err = abs(y-f);

Затем отсортируйте вектор ошибки

[val, idx] = sort(err);

И используйте отсортированные индексы, чтобы отсортировать ваши значения y

y2 = y(idx);

Теперь y2 имеет те же значения, что и y, но сначала ближе к подходящему значению.

Сделайте то же самое для x, чтобы вычислить x2, чтобы у вас было соответствие между x2 и y2.

x2 = x(idx);
person Sembei Norimaki    schedule 28.02.2017

Сембей Норимаки хорошо объяснил ваш основной вопрос, поэтому я рассмотрю ваш второстепенный вопрос = является ли полифит правильной функцией?

Линия наилучшего соответствия определяется как линия со средней ошибкой, равной нулю.

Если это должна быть «линия», мы могли бы использовать полифит, который будет соответствовать многочлену. Конечно, «прямая» может быть определена как полином первой степени, но полиномы первой степени обладают некоторыми свойствами, облегчающими работу с ними. Полиномиальное (или линейное) уравнение первого порядка, которое вы ищете, должно иметь следующую форму:

y = mx + b

где y — ваша зависимая переменная, а X — ваша независимая переменная. Итак, задача такова: найти такие m и b, чтобы смоделированный y был как можно ближе к фактическому y. Как оказалось, ошибка, связанная с линейной подгонкой, является выпуклой, то есть имеет одно минимальное значение. Чтобы вычислить это минимальное значение, проще всего объединить векторы смещения и x следующим образом:

Xcombined = [x.' ones(length(x),1)];

затем использовал нормальное уравнение, полученное из минимизации ошибки

beta = inv(Xcombined.'*Xcombined)*(Xcombined.')*(y.')

отлично, теперь наша линия определяется как Y = Xcombined*beta. чтобы нарисовать линию, просто возьмите образец из некоторого диапазона x и добавьте член b

Xplot = [[0:.1:5].' ones(length([0:.1:5].'),1)];
Yplot = Xplot*beta;
plot(Xplot, Yplot);

Так почему же полифит так плохо работает? ну, я не могу сказать наверняка, но моя гипотеза состоит в том, что вам нужно поменять местами ваши матрицы x и y. Я предполагаю, что это дало бы вам гораздо более разумную линию.

x = x.';
y = y.';

тогда попробуй

p = polyfit(x,y,n)

Надеюсь, это поможет. Один мудрый человек однажды сказал мне (и я узнаю это каждый день): не доверяй алгоритму, которого не понимаешь!

person David Kaftan    schedule 01.03.2017
comment
x и y являются векторами, их перестановка не даст никакого эффекта. Пример в вопросе имеет очень плохие результаты регрессии, потому что, как вы можете видеть, корреляция данных очень низкая. Регрессия не может творить чудеса, поэтому, если вы хотите уместить линию в данных с низкой корреляцией, вы должны ожидать большую ошибку. В любом случае хороший совет от мудрого человека. - person Sembei Norimaki; 01.03.2017
comment
Да, оглядываясь назад, не знаю, о чем я думал. Нет абсолютно никаких причин, чтобы это было проблемой. Думаю, я думал, что он может рассматривать обучающий набор как набор данных с 5 функциями и 1 выборкой. - person David Kaftan; 05.12.2018

Вот некоторый тестовый код, который может помочь кому-то еще, имеющему дело с линейной регрессией и методом наименьших квадратов.

%https://youtu.be/m8FDX1nALSE код Matlab

%https://youtu.be/1C3olrs1CUw хорошее видео для ручной работы, если вы хотите протестировать

function [a0 a1] = rtlinreg(x,y) 
  x=x(:);
  y=y(:);
  n=length(x);
  a1 = (n*sum(x.*y) - sum(x)*sum(y))/(n*sum(x.^2) - (sum(x))^2);  %a1 this is the slope of linear model
  a0 = mean(y) - a1*mean(x); %a0 is the y-intercept
end

x=[65,65,62,67,69,65,61,67]'
y=[105,125,110,120,140,135,95,130]'

[a0 a1] = rtlinreg(x,y);  %a1 is the slope of linear model, a0 is the y-intercept

x_model =min(x):.001:max(x);
y_model = a0 + a1.*x_model;  %y=-186.47 +4.70x   
plot(x,y,'x',x_model,y_model)
person Rick T    schedule 01.03.2017