2017-02-28 6 views
1

J'essaie de trouver la ligne qui correspond le mieux aux données. J'utilise le code suivant ci-dessous, mais maintenant Je veux que les données soient placées dans un tableau trié afin qu'il ait les données les plus proches de la ligne, comment puis-je faire cela? Aussi est polyfit la fonction correcte à utiliser pour cela?trouver la ligne qui correspond le mieux aux données

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,'-') 

Image

PS: J'utilise Octave 4.0 qui est similaire à Matlab

Répondre

2

Vous pouvez d'abord calculer l'erreur entre la valeur réelle y et la valeur prédite f

err = abs(y-f); 

Ensuite, triez le vecteur d'erreur

[val, idx] = sort(err); 

Et utiliser les index triés pour avoir vos valeurs y trié

y2 = y(idx); 

Maintenant y2 a les mêmes valeurs que y mais les plus proches de la valeur de pose d'abord.

Faites la même chose pour x pour calculer x2 si vous avez une correspondance entre x2 et y2

x2 = x(idx); 
1

Sembei Norimaki a fait un bon travail d'expliquer votre première question, je vais donc regarder votre question secondaire = est polyfit la bonne fonction?

La ligne de meilleur ajustement est définie comme la ligne ayant une erreur moyenne de zéro.

S'il s'agit d'une "ligne", nous pourrions utiliser polyfit, qui s'adaptera à un polynôme. Bien sûr, une "ligne" peut être définie comme un polynôme du premier degré, mais les polynômes du premier degré ont des propriétés qui facilitent la gestion. La première équation que vous cherchez devrait venir sous cette forme polynomiale d'ordre (ou linéaire):

y = mx + b 

où y est la variable dépendante et X est la variable indépendante. Le défi est donc le suivant: trouver le m et le b tels que le y modélisé soit aussi proche que possible du y réel. Comme il s'avère, l'erreur associée à un ajustement linéaire est convexe, ce qui signifie qu'il a une valeur minimale. Pour calculer cette valeur minimale, il est plus simple de combiner le biais et les vecteurs x comme suit:

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

ensuite utilisé l'équation normale, dérivée de la minimisation de l'erreur

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

grand, maintenant notre ligne est définie comme Y = Xcombined * beta. de tracer une ligne, il suffit de l'échantillon une gamme de x et ajouter le b terme

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

Alors, pourquoi fonctionne-t-polyfit si mal? bien, je ne peux pas dire avec certitude, mais mon hypothèse est que vous avez besoin de transposer vos matrices x et y. Je suppose que cela vous donnerait une ligne beaucoup plus raisonnable.

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

puis essayez

p = polyfit(x,y,n) 

J'espère que cela aide. Un homme sage m'a dit une fois (et comme j'apprends tous les jours), ne faites pas confiance à un algorithme que vous ne comprenez pas!

+0

'x' et' y' sont des vecteurs, leur transposition n'aura aucun effet. L'exemple de la question a de très mauvais résultats de régression car, comme vous pouvez le voir, la corrélation des données est très faible. La régression ne peut pas faire de magie, donc si vous voulez insérer une ligne dans une donnée faiblement corrélée, vous devriez vous attendre à une grosse erreur. Quoi qu'il en soit, un bon conseil du sage. –

-1

est ici un code de test qui peut aider quelqu'un à traiter les autres avec la régression linéaire et moindres carrés

% https://youtu.be/m8FDX1nALSE code Matlab

% https://youtu.be/1C3olrs1CUw bonne vidéo pour travailler à la main si vous voulez tester

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)