2 votes

Valeur estimée par Python à partir de l'ajustement de la courbe

J'essaie d'écrire un code Python très basique qui sort un nombre basé sur un échantillon d'entrées et de sorties. Donc par exemple si :

x  = [1, 2, 3, 4, 5]
y = [2, 5, 10, 17, 26]

z = np.interp(7, xp, yp)
print(z)  ##expected 50, actual was 26

J'aimerais pouvoir trouver une fonction de meilleur ajustement qui associe ces valeurs afin de pouvoir lui passer une autre valeur x et obtenir une approximation approximative de la valeur y. J'ai essayé de lire sur scipy.optimize.curve_fit mais pour autant que je sache, ce n'est pas ce que je devrais utiliser car cela utilise une fonction prédéfinie que je n'ai pas dans mon cas.

Notez que je n'ai aucune restriction quant à savoir si la fonction doit être linéaire/périodique/quadratique, etc. parce que mes valeurs varieront, mais je suppose que la plupart des fonctions doivent être linéaires.

J'ai aussi essayé numpy.interp mais je n'obtiens que la dernière valeur dans le y pour n'importe quel x J'entre.

EDITAR: Après avoir essayé la réponse de Cleb et l'avoir comparée avec l'approche originale de kennytm, voici mes conclusions. enter image description here La technique la plus précise ici devrait être la fonction qui est la plus proche de la ligne rouge. La ligne verte représente l'approche de kennytm (la régression quadratique est la plus précise que j'ai essayée) et la ligne noire représente la technique de Cleb (UnivariateSpline). Il semble que, puisque UnivariateSpline n'a aucune connaissance préalable du modèle sous-jacent, il s'adapte un peu mieux aux valeurs de la fonction, ce qui le rend un peu plus précis.

3voto

Cleb Points 9410

Une autre option consiste à utiliser une spline, par exemple. scipy.interpolate.UnivariateSpline si vous ne vous souciez pas du modèle sous-jacent (par exemple, s'il est linéaire, cubique, etc.) et l'overfitting.

Alors tu peux juste faire :

from scipy.interpolate import UnivariateSpline

x  = [1, 2, 3, 4, 5]
y = [2, 5, 10, 17, 26]
spl = UnivariateSpline(x, y)

Pour obtenir un devis à x=7 vous pouvez maintenant le faire tout simplement :

spl(7)

qui renvoie la valeur attendue :

array(49.99999999999993)

Cette approche permet d'éviter la définition d'un modèle.

2voto

KennyTM Points 232647

J'ai essayé de lire sur scipy.optimize.curve_fit mais pour autant que je sache, ce n'est pas ce que je devrais utiliser car cela utilise une fonction prédéfinie que je n'ai pas dans mon cas.

En fait, cette fonction pour scipy.optimize.curve_fit est le modèle que vous voulez ajuster. Disons que vous voulez une régression linéaire, alors vous utilisez :

def linear(x, a, b):
    return a*x + b

fit_params, _ = scipy.optimize.curve_fit(linear, xp, yp)
print(linear(7, *fit_params))
# 36.0

Idem pour la régression quadratique, etc :

def quadratic(x, a, b, c):
    return a*x*x + b*x + c

fit_params, _ = scipy.optimize.curve_fit(quadratic, xp, yp)
print(quadratic(7, *fit_params))
# 50.000000000004555

(La deuxième valeur de retour de curve_fit est la matrice covariante de la sortie, qui donne une image approximative de la qualité de l'ajustement)


Si vous voulez simplement ajuster un polynôme avec les moindres carrés, vous pouvez simplement utiliser numpy.polyfit .

linear_coeff = numpy.polyfit(xp, yp, deg=1)
print(numpy.polyval(linear_coeff, 7))
# 35.999999999999986

quadratic_coeff = numpy.polyfit(xp, yp, deg=2)
print(numpy.polyval(quadratic_coeff, 7))
# 50.000000000000085

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X