Semaine 3 · Jour 2 · 420-SN1

DES MESURES
AUX MODÈLES

Ajuster, interpoler, prédire : quand un nuage de points devient une loi

Des points... mais quelle loi ?

temps mesure
Comprendre la tendance
Combler les trous (interpoler)
Prédire au-delà (extrapoler)

Une expérience donne des points de mesure. Pour en tirer quelque chose, on cherche la courbe qui les résume : une loi mathématique. Python sait la trouver à notre place - c'est tout l'objet de ce cours.

Partie 1

LES TECHNIQUES

Cinq outils pour passer d'un nuage de points à une loi

L'arsenal en un coup d'œil

OutilCe qu'il faitQuand l'utiliser
np.polyfittrouve les coefficients d'un polynôme (droite, parabole...)tendance simple
np.poly1demballe ces coefficients en fonction modele()évaluer, prédire
curve_fittrouve les coefficients d'une forme qu'on écrit (exp, sinus...)courbe non polynomiale
np.interpestime entre deux points (segments droits)combler un trou, vite
interp1dcourbe lisse passant par tous les pointscombler en douceur

Deux familles : ajuster (trouver la loi : polyfit, curve_fit) et interpoler (combler entre les mesures : np.interp, interp1d). On les voit une à une, puis on choisit.

Ajuster une droite : polyfit

import numpy as np temps = np.array([1, 2, 3, 4, 5]) mesures = np.array([2.1, 4.3, 6.0, 8.2, 9.9]) coefficients = np.polyfit(temps, mesures, 1) pente, ordonnee = coefficients # ≈ 1.95 , 0.13

np.polyfit(temps, mesures, 1) cherche la droite de meilleur ajustement (degré 1) et renvoie ses coefficients : la pente et l'ordonnée à l'origine de y = pente·x + ordonnee. C'est Python qui trouve les coefficients à partir des données.

Le modèle devient une fonction

# on transforme les coefficients en fonction modele = np.poly1d(coefficients) print(modele(3)) # 5.98 -> la valeur du modele a t=3 print(modele(6)) # 11.8 -> une prediction !

np.poly1d(coefficients) emballe les coefficients dans une vraie fonction : on lui donne un temps, elle renvoie la valeur du modèle. C'est l'outil clé : une fois le modèle trouvé, on l'évalue partout - même là où on n'a pas mesuré.

Et si ce n'est pas une droite ?

Une parabole : degré 2
coefficients = np.polyfit( temps, mesures, 2) # a*x**2 + b*x + c
Un modèle au choix : curve_fit
from scipy.optimize import curve_fit def refroidissement(temps, amplitude, taux): return amplitude * np.exp(taux * temps) coefficients, _ = curve_fit( refroidissement, temps, mesures)

Pour une parabole, on monte le degré de polyfit. Pour une forme quelconque (exponentielle, sinus...), on écrit la fonction et curve_fit (de scipy) en trouve les coefficients. La règle : on choisit la forme, Python trouve les nombres.

Interpoler : combler entre les points

# on a mesure a t=2 et t=3, mais pas a t=2.5 valeurEstimee = np.interp(2.5, temps, mesures) print(valeurEstimee) # 5.15 (entre 4.3 et 6.0) # courbe lisse qui passe par tous les points : from scipy.interpolate import interp1d courbe = interp1d(temps, mesures, kind="cubic")

L'interpolation estime une valeur entre deux mesures connues. np.interp relie les points par des segments droits ; scipy.interpolate trace une courbe lisse (splines) qui passe exactement par chaque point.

Prédire : prolonger le modèle

# notre modele a ete ajuste sur t = 1 a 5 tempsFuturs = np.array([6, 7, 8]) valeursPredites = modele(tempsFuturs) print(valeursPredites) # [11.8 13.8 15.7] -> le futur estime

Une fois le modèle trouvé, prédire = l'évaluer au-delà des mesures. On donne des temps futurs, le modèle renvoie les valeurs attendues. C'est ainsi qu'on estime une trajectoire, une population, une température à venir.

⚠ Le piège de l'extrapolation

données au-delà

Un modèle n'est fiable que là où il y a des données. Au-delà, il peut diverger totalement - surtout un polynôme de degré élevé qui explose. Extrapoler loin, c'est deviner.

Règle d'or : prédire un peu au-delà, oui ; très loin, prudence.

Le choix : interpoler ou ajuster ?

InterpolationRégression (ajustement)
Les pointspasse exactement par touslisse la tendance, ignore le bruit
Le bruitle suit (même les erreurs)le gomme
Sert àcombler un trou internecomprendre la loi, prédire
Outilnp.interp, interp1dnp.polyfit, curve_fit

Maintenant qu'on a les outils : l'interpolation fait confiance à chaque point (idéale entre des mesures fiables) ; la régression cherche la tendance générale malgré le bruit (idéale pour prédire).

Partie 2

RECONNAÎTRE
LA FORME

Quelle courbe pour quel nuage ? Un menu de recettes

Le menu des formes

Droite

polyfit(x, y, 1)
proportionnel, linéaire

Parabole

polyfit(x, y, 2)
chute, trajectoire

Puissance

curve_fit(a*x**b)
masse-rayon, Kepler

Exponentielle

curve_fit(a*np.exp(b*x))
croissance, radioactivité

Saturation

curve_fit(a*(1-np.exp(-b*x)))
charge, refroidissement

Sinus

curve_fit(a*np.sin(b*x+c))
oscillation, marées
La recette : on regarde le nuage, on choisit la forme, Python trouve les nombres

Droite → la loi d'Ohm

Domaine : électricité
courant tension
courant = np.array([.1,.2,.3,.4,.5]) # A tension = np.array([.47,.96,1.40,1.89,2.34]) # V resistance, _ = np.polyfit(courant, tension, 1) print(resistance) # ≈ 4.7 Ω (U = R·I)

La tension est proportionnelle au courant : une droite qui part de zéro. La pente est la résistance du composant. Même forme : allongement d'un ressort (Hooke), dilatation d'un métal.

Parabole → distance de freinage

Domaine : sécurité routière
vitesse distance
vitesse = np.array([20,40,60,80,100]) # km/h distance = np.array([3,12,27,48,75]) # m modele = np.poly1d(np.polyfit(vitesse, distance, 2)) print(modele(50)) # ≈ 19 m a 50 km/h

La distance de freinage croît comme le carré de la vitesse : doubler la vitesse quadruple la distance d'arrêt. Même forme : trajectoire d'un projectile, chute libre.

Puissance → la loi de Kleiber

Domaine : biologie
masse métabolisme
masse = np.array([.02,.5,5,70,4000]) # kg metab = np.array([.18,2,11.4,82,1710]) # W def loiPuissance(m, a, b): return a*m**b (a, b), _ = curve_fit(loiPuissance, masse, metab) print(b) # ≈ 0.75 : souris → éléphant

Le métabolisme d'un animal croît comme sa masse à la puissance 3/4 - de la souris à la baleine. Même forme : Kepler (T²∝a³), masse-rayon des planètes, surface vs volume.

Exponentielle → le carbone 14

Domaine : archéologie / physique nucléaire
temps C14 restant
annees = np.array([0,2000,4000,6000,8000]) fraction = np.array([1,.785,.617,.484,.380]) def decroissance(t, a, b): return a*np.exp(b*t) (a, b), _ = curve_fit(decroissance, annees, fraction) print(np.log(2)/-b) # ≈ 5730 ans : la demi-vie !

Tous les 5730 ans, la moitié du carbone 14 d'un fossile disparaît : on date l'os par la fraction restante. Même forme : refroidissement, médicament éliminé, intérêts composés (croissance).

Saturation → un médicament en perfusion

Domaine : médecine / pharmacologie
temps concentration
heures = np.array([0,1,2,4,8]) conc = np.array([0,3.9,6.3,8.6,9.8]) # mg/L def saturation(t, a, b): return a*(1-np.exp(-b*t)) (plateau, b), _ = curve_fit(saturation, heures, conc) print(plateau) # ≈ 10 mg/L : le palier

La concentration monte vite puis plafonne à l'équilibre dose/élimination : le palier sert à doser sans surdose. Même forme : charge d'un condensateur, remplissage d'un réservoir.

Sinus → les marées

Domaine : océanographie
temps hauteur
temps = np.array([0,2,4,6,8,10,12]) # h hauteur = np.array([3,4.7,4.6,2.9,1.2,1.3,3.1]) def onde(t, a, b, c, d): return a*np.sin(b*t+c)+d (a, b, c, d), _ = curve_fit(onde, temps, hauteur, p0=[2,.5,0,3]) print(2*np.pi/b) # ≈ 12 h : la période

Le niveau de la mer oscille autour d'une moyenne ; l'ajustement retrouve la période (~12 h) et l'amplitude. Même forme : son, courant alternatif, températures saisonnières, rythmes biologiques.

Le truc des astronomes : log-log

normal log-log
# une loi de puissance... # ...devient une DROITE en log-log pente, _ = np.polyfit( np.log(rayons), np.log(masses), 1) # la pente = l'exposant b !

Une loi y = a·x^b devient une droite quand on prend le logarithme des deux axes : sa pente est l'exposant. C'est ainsi qu'on lit Kepler ou la relation masse-rayon d'un seul coup d'œil.

Partie 3

DES IDÉES
CONCRÈTES

Choisis tes données, choisis ton modèle

Un sujet, des données, un modèle

SujetDonnées à récolterRelationOutil
Exoplanètesrayon, masseloi de puissance masse-rayoncurve_fit
Exoplanètespériode, distance à l'étoileKepler T² ∝ a³curve_fit
Lunes de Jupiterdistance, périodeKepler (exposant ≈ 1.5)curve_fit
Trous noirsmasse, rayon de Schwarzschilddroite exacte R = 2.95·Mpolyfit deg 1
Galaxiesdistance, vitesse de fuiteloi de Hubble v = H₀·dpolyfit deg 1

Toutes ces données existent en CSV public (NASA Exoplanet Archive, tables d'astronomie). Le geste est toujours le même : un nuage, une forme, un ajustement, une prédiction.

La droite qui a révélé l'Univers

distance vitesse
distances = np.array([50,100,150,200,250]) vitesses = np.array([3400,7200,10300,14100,17600]) H0, _ = np.polyfit(distances, vitesses, 1) print(H0) # ≈ 70 km/s par Mpc

En 1929, Hubble trace vitesse de fuite vs distance des galaxies : une droite. Sa pente, la constante de Hubble H₀, dit que l'Univers est en expansion - et son inverse 1/H₀ donne son âge. Une simple polyfit degré 1 sur de vraies mesures.

La démarche, en 4 gestes

  • 1. Mesurer - récolter les points (temps, mesure)
  • 2. Choisir une forme - droite, parabole, exponentielle...
  • 3. Ajuster - polyfit / curve_fit trouvent les coefficients
  • 4. Utiliser - interpoler (combler) et prédire (modele(temps))

Des données brutes à une loi qui prédit : c'est le cœur du calcul scientifique. Les fonctions plus puissantes (équations différentielles, Fourier, optimisation...) t'attendent dans l'En savoir plus.

À TON CARNET !

Mesure quelques points, ajuste une droite avec polyfit, puis prédis une valeur future
⤺ Refermer le diaporama