web-dev-qa-db-fra.com

Ajuster un seul paramètre d'une fonction avec plusieurs paramètres en python

En python, j'ai une fonction qui a beaucoup de paramètres. Je souhaite adapter cette fonction à un ensemble de données, mais en utilisant un seul paramètre, le reste des paramètres que je souhaite fournir par moi-même. Voici un exemple:

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

for b in xrange(10):
   popt,pcov = curve_fit(func,x1,x2)

En cela, je veux que l'ajustement ne soit fait que pour a et que le paramètre b prenne la valeur de la variable de boucle. Comment cela peut-il être fait?

31
lovespeed

Vous pouvez envelopper func dans un lambda, comme suit:

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

for b in xrange(10):
   popt,pcov = curve_fit(lambda x, a: func(x, a, b), x1, x2)

Un lambda est une fonction anonyme qui, en Python, ne peut être utilisée que pour des fonctions simples à une ligne. Fondamentalement, il est normalement utilisé pour réduire la quantité de code lorsqu'il n'est pas nécessaire d'attribuer un nom à la fonction. Une description plus détaillée est donnée dans la documentation officielle: http://docs.python.org/tutorial/controlflow.html#lambda-forms

Dans ce cas, un lambda est utilisé pour corriger l'un des arguments de func. La fonction nouvellement créée n'accepte que deux arguments: x et a, alors que b est fixé à la valeur extraite de la variable locale b. Cette nouvelle fonction est ensuite passée à curve_fit en tant qu'argument.

40
Anton Beloglazov

Au lieu d'utiliser la fonction lambda, qui est peut-être moins intuitive à digérer, il est recommandé de spécifier le scikit curve_fit paramètre bounds qui forcera la recherche dans les paramètres dans les limites personnalisées. 

Tout ce que vous avez à faire est de laisser votre variablease déplacer entre -inf et + inf et votre variablebentre (b- epsilon) et (b+ epsilon)

Dans votre exemple: 

epsilon = 0.00001

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

for b in xrange(10):
    popt,pcov = curve_fit(func,x1,x2, bounds=((-np.inf,b-epsilon), (np.inf,b+epsilon))
1
bobo32

Curve_fit de Scipy prend trois arguments de position, func, xdata et ydata. Une autre approche (utiliser un wrapper de fonction) consiste donc à traiter 'b' comme xdata (c.-à-d. Une variable indépendante) en construisant une matrice xdata original (x1) et une deuxième colonne pour votre paramètre fixe b.

En supposant que x1 et x2 sont des tableaux:

def func(xdata,a):
   x, b = xdata[:,0], xdata[:,1]  # Extract your x and b
   return a*x*x + b

for b in xrange(10): 
   xdata = np.zeros((len(x1),2))  # initialize a matrix
   xdata[:,0] = x1  # your original x-data
   xdata[:,1] = b  # your fixed parameter
   popt,pcov = curve_fit(func,xdata,x2)  # x2 is your y-data
0
Arjan Groen