Curve fitting sur python (non polynomial)

AmbrePh - 17 janv. 2024 à 12:33
mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 - 25 janv. 2024 à 20:28

Bonjour à  tous,

Je cherche à fitter mes données au modèle suivant de diffusion appliqué à mes conditions limites : 

Seul le paramètre D est variable et à déterminer par ce fitting. 

Voilà le code que j'ai écris pour le moment.? Cependant, je me retrouve avec une approximation à 0 dans un de mes vecteurs (dû au calcul de y[i]/hinf), ce qui fausse totalement l'approximation de D. Il me semble que la fonction curve_fitting de numpy n'est pas très adaptée pour cette résolution... 

import numpy as np
from scipy.optimize import fsolve, least_squares, curve_fit
import matplotlib.pyplot as plt

# Paramètres à modifier suivant l'échantillon
h0 = 0.001 # en m
c0 = 12.3 # en %w
hinf = h0*1.005 # en m
K = 1 # sans unité
S = 10**-3 # en mol/mol
F = 5*(10**-7) # en m3/s
As = 0.05 # en m2

# === guess values
D0 = 10**-10
B = (K*S*F)/(As*D0)
bounds = [0, np.inf]

# Calcul de gamma n
def gamma (a):
	def equa (x, a):
		return x * np.tan(x) - a
	x_values = np.linspace(1, 100, 100)
	solutions = fsolve(equa, x_values, args=(a,))
	return solutions

y = gamma (B*hinf)

# Calcul du modèle
def GEX (t,D):
    imin = 0
    imax = 100
    gexf = 0
    A = 0
    for i in range (imin, imax):
        A += (np.sin(y[i])/(y[i]*(np.sin(2*y[i])+hinf)))*np.exp(-((y[i]/hinf)**2)*D*t)
    gexf = 4*c0*hinf*A
    return gexf

# Récupération des datas
filename = 'U:/Data/Théorie/Diffusion BBSA/D_BBSA 100bars.csv' # Mettre ici le chemin d'accès au fichier de données
data = np.genfromtxt(filename, delimiter=',')
tps = data[:,0] #le temps en min
CC = data[:,1] #la concentration

# res = least_squares(fungex, D0, loss='soft_l1', method='trf', bounds=bounds, arg=(tps, CC), tr_options={True})
res, cost = curve_fit(GEX, tps,CC,D0, method='lm')

# Calcul du coeffcient de diffusion
D = float(res)/60 #en m2/s
print ("Le coefficient de diffusion est", D)

# Courbe d'ajustement
tps1 = np.linspace(min(tps), max(tps), 20)
resu_th = GEX(tps1, res)

# === Affichage graphes ========================
plt.plot(tps,CC, 'o', label='expérimental')
plt.text(10, 0.01, 'D= ' + format(D,'0.03E') + ' m²/s')
plt.xscale('linear')
plt.yscale('linear')
plt.xlabel("t (min)")
plt.ylabel("C (%w)")

plt.legend(loc='upper right')
plt.plot(tps1,resu_th, '-')
plt.show()

# =============================================================================

Auriez vous une solution à me proposer ? Je ne connais pas d'autres fonction qui permette de fitter des data expérimentales. 

Merci ! 


Windows / Chrome 120.0.0.0

1 réponse

mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 7 752
25 janv. 2024 à 20:28

Bonjour,

Je n'ai pas compris ta question. Pour moi selon la nature de tes données, tu vas choisir un modèle et ensuite tenter de trouver les hyper paramètres de ce modèle par rapport à tes données d'entraînement (fit). Si tu trouves les bons hyper-paramètres, étant donné une donnée d'entrée arbitraire, le modèle entraîné retournera une donnée de sortie proche de celle attendue.

Prenons un exemple très simple. Tu as un ensemble de points {(x, y)} plus ou moins alignés et tu cherches à trouver la droite d'équation y = a.x + b qui les résume. Les hyper-paramètres sont a et b. Si tu as un bon échantillon de couples (x, y), tu devrais pouvoir apprendre a et b. Comme ici on s'attend à trouver une fonction affine, une régression linéaire peut être un bon modèle d'apprentissage.

Prenons un exemple plus compliqués. Tu as un ensemble de points colorés dans un espace de dimension N, soit en bleu soit en rouge. Ton but est de trouver un hyperplan qui sépare les points rouges des points bleus autant que possible (donc par exemple, si tu travailles dans le plan, tu cherches une droite qui les sépare). Dans ce cas, un réseau de neurone à un neurone peut suffire (si un tel hyperplan séparateur existe). Dans des cas moins triviaux, il faudrait plus de neurones (et donc utiliser un réseau de neurones).

Dans ta question, tu ne précises ni la nature de tes données (ce qui ne permet pas de choisir un ensemble de modèles candidats), ni les modèles que tu serais prêt à considérer. Peut-être que faire un petit état de l'art des techniques de machine learning dans ton domaine d'étude (peut-être en te promenant dans la documentation de scilab ou scikit-learn) t'aidera.

En tout cas, faute de plus d'information, je ne vois pas trop comment on peut répondre à ta question. Et hélas, ton extrait de code python ne permet pas réellement de comprendre ce que tu cherches à faire.

Bonne chance

0