Tutoriel Python & SciPy : notion d’interpolation
Table des matières
Interpolation : Définition générale
Interpolation univariée ou 1-D
Interpolation avec la fonction radial basis
Introduction :
Bienvenue dans un nouveau tutoriel Python, aujourd’hui nous allons nous nous intéresser à la notion d’interpolation avec Scipy. L’interpolation est le processus de générer un ensemble de points entre deux points donnés. Nous allons découvrir ce qu’est l’interpolation, les différents types d’interpolation (uni variée , spline , multivariée) … Ne vous inquiétez pas nous expliquerons toutes ces notions dans les sections du cours.
À la fin de ce tutoriel, vous serez capable de réaliser plusieurs types d’interpolation sur des données unidimensionnelle et multidimensionnelle ainsi que sur des données structurées ou non structurées.
Ce cours sera riche en exemple et exercices applicatifs et leurs corrections afin de vous permettre de passer à la pratique, car pour apprendre une notion en programmation, il faut absolument coder des exemples.
Nous estimons que vous avez une idée générale sur le contenu de ce tutoriel. Commençons alors !
Interpolation : Définition générale
L’interpolation est le processus de générer des points entre des points donnés. Par exemple, entre les points 3 et 4 on peut trouver 3.1111 et 3.1222 en gros une infinité de point !
L’interpolation a beaucoup d’utilisation, dans l’apprentissage automatique par exemple nous traitons souvent des données manquantes dans un ensemble de données, l’interpolation est souvent utilisée pour substituer ces valeurs . Cette méthode de remplissage des valeurs est appelée imputation .Outre l’imputation, l’interpolation est souvent utilisée lorsque nous devons lisser les points discrets d’un ensemble de données.
Le module Scipy.interpolate :
SciPy nous fournit un module appelé scipy.interpolate qui a de nombreuses fonctions pour traiter l’interpolation.
Ce sous-package contient des classes et des fonctions spline, des classes d’interpolation 1-D et multidimensionnelles (uni variées et multivariées) ainsi que des interpolateurs polynomiaux.
Chacune de ces classes à des méthodes et fonctionnalités multiples. Nous allons les voir en détail dans les sections qui suivent.
Exemple :
Créons quelques données et voyons comment cette interpolation peut être faite en utilisant le paquet scipy.interpolate :
Syntaxe :
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
a = np.linspace(0, 3, 10)
b = np.cos(a**2/5+2)
print (a,b)
Résultat de l’éxécution :
Maintenant, nous avons deux tableaux. En supposant que ces deux tableaux sont les deux dimensions des points dans l’espace, traçons à l’aide du programme suivant et voyons à quoi ils ressemblent.
plt.plot(a, b,'o')
plt.show()
Résultat de l’exécution :
Interpolation univariée ou 1-D :
La classe interp1d dans scipy.interpolate est une méthode pratique pour créer une fonction basée sur des points de données , qui peut être évaluée n’importe où dans le domaine défini par les données en utilisant l’interpolation linéaire.
Elle prend comme paramètre les points x et y et retourne une fonction exécutable qui peut être appelée avec un nouveau x et retourne le y correspondant.
Exemple :
Pour x_s et y_s donnés on interpole les valeurs de 1.1 à 1.9 .
Syntaxe :
from scipy.interpolate import interp1d
import numpy as np
x_s = np.arange(8)
y_s = 2*x_s + 3
fonction_interp= interp1d (x_s, y_s)
nouveau_tab = fonction_interp(np.arange (1.1, 2, 0.1))
print(nouveau_tab)
Résultat de l’exécution :
Remarque : devrait être dans la même plage que l’ancien xs, ce qui signifie que nous ne pouvons pas appeler interp_func() avec des valeurs supérieures à 8, ou inférieures à 0.
Voilà ce qui se passe si on essaye de passer des valeurs supérieures à 8.
Syntaxe :
from scipy.interpolate import interp1d
import numpy as np
x_s = np.arange(8)
y_s = 2*x_s + 3
fonction_interp= interp1d (x_s, y_s)
nouveau_tab = fonction_interp(np.arange (1.1, 11, 0.1))
print(nouveau_tab)
Résultat de l’exécution :
Exemple :
En utilisant les données a et b du premier exemple, créons une fonction d’interpolation et dessinons un nouveau graphique interpolé.
Syntaxe :
c1 = interp1d(a, b,kind = 'linear')
c2 = interp1d(a, b, kind = 'cubic')
En utilisant la fonction interp1d, nous avons créé deux fonctions c1 et c2. Ces fonctions, pour une entrée donnée x retourne y. Le troisième type de variable représente le type de la technique d’interpolation. 'Linear', 'Nearest', 'Zero', 'Slinear', 'Quadratic', 'Cubic' sont quelques techniques d’interpolation.Maintenant, créons une nouvelle entrée plus longue pour voir la nette différence d’interpolation. Nous utiliserons la même fonction que les anciennes données sur les nouvelles données.
x_nouv = np.linspace(0, 3,30)
plt.plot(a, b, 'o', x_nouv, c1(x_nouv), '-', xnew, c2(x_nouv), '--')
plt.legend(['data', 'linear', 'cubic','nearest'], loc = 'best')
plt.show()
Résultat de l’exécution :
Voici la sortie du programme :
Interpolation Spline :
Pour tracer des courbes lisses à travers des points de données, les dessinateurs utilisaient autrefois de fines bandes souples de bois, de caoutchouc dur, de métal ou de plastique appelées cannelures mécaniques. Pour utiliser une cannelure mécanique, les broches ont été placées à un choix judicieux de points le long d’une courbe dans une conception, puis la cannelure a été pliée, de sorte qu’elle touche chacune de ces broches.Clairement, avec cette construction, la cannelure interpole la courbe à ces broches. Il peut être utilisé pour reproduire la courbe dans d’autres dessins. Les points où les goupilles sont situées sont appelés nœuds. On peut modifier la forme de la courbe définie par la cannelure en ajustant l’emplacement des nœuds.
Spline uni variée :
La courbe de lissage unidimensionnelle correspond à un ensemble donné de points de données. La classe UnivariateSpline dans scipy.interpolate est une méthode pratique pour créer une fonction, basée sur des points de données fixes classe – scipy.interpolate .
class scipy.interpolate.UnivariateSpline(x, y, w=None, bbox=[None, None], k=3, s=None, ext=0, check_finite=False)
Les paramètres de la fonction interpolate.univariateSpline sont les suivants :
x : tableau 1-D de données d’entrée indépendantes. Doit augmenter ; doit être strictement augmenté si s vaut 0.
y : Tableau 1-D de données d’entrée dépendantes, de la même longueur que x.
w : Poids pour raccord cannelé. Doit être positif. Si aucun (par défaut), les poids sont tous égaux.
bbox : 2-séquence spécifiant la limite de l’intervalle d’approximation. Si None (par défaut), bbox=[x[0], x[-1]].
k : Degré de la courbe de lissage. Doit être 1 = k = 5. La valeur par défaut est k = 3, une courbe cubique.
s : Facteur de lissage positif utilisé pour choisir le nombre de nœuds. Le nombre de nœuds sera augmenté jusqu’à ce que la condition de lissage soit satisfaite
ext : Contrôle le mode d’extrapolation pour les éléments qui ne sont pas dans l’intervalle défini par la séquence de nœuds.
check_finite : Vérifier si les tableaux d’entrée ne contiennent que des nombres finis
Exemple :
Trouver l’interpolation de spline univariée pour 3.1, 3.2... 3.9 pour les points non linéaires suivants :
Syntaxe :
from scipy.interpolate import UnivariateSpline
import numpy as np
x_s = np.arange(10)
y_s = x_s**2 + np.sin(x_s) + 1
fonction_interp= UnivariateSpline(x_s, y_s)
nouv_tab = fonction_interp(np.arange(3.1, 4, 0.1))
print(nouv_tab)
Résultat de l’exécution :
Exemple :
Voici un exemple de l’utilisation de univariateSpline avec le plot :
Syntaxe :
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
a = np.linspace(-2, 2, 50)
b = np.exp(-x**2) + 0.2* np.random.randn(50)
plt.plot(a, b, 'ro', ms = 5)
plt.show()
Résultat de l’exécution :
Interpolation multi variée :
Ce type d’interpolation est utilisé lorsqu’on a des données non structurés de multiple dimension :
Interpolation multi-variée 2-D avec scipy.interpolate.griddata :
Cette fonction permet d’interpoler les données multidimensionnelles.
Exemple :
Dans cet exemple, supposons qu’on veut interpoler la fonction 2-D sur une grille [0,1] x[0,1] mais qu’on ne connaît les valeurs de cette interpolation à seulement 1000 points :
Syntaxe :
#définition de la fonction qui calcule les valeurs interpolés
def fonction (a, b):
return a*(2-a)*np.cos(4*np.pi*a) * np.sin(5*np.pi*b**2)**2
#choix de la grille
grille_x, grille_y = np.mgrid [0:1:100j, 0:1:200j]
#valeurs d’interpolation des 100 points
points = np.random.rand(1000, 2)
valeurs = fonction (points [:,0], points [:,1])
Cela peut être fait avec griddata – ci-dessous nous essayons toutes les méthodes d’interpolation :
#méthode griddata
from scipy.interpolate import griddata
premier_grid = griddata (points, valeurs, (grille_x, grille_y), method='nearest')
deuxieme_grid = griddata (points, valeurs, (grille_x, grille_y), method='cubic')
troisieme_grid = griddata (points, valeurs, (grille_x, grille_y), method='linear')
Maintenant voici ce qu’affichent les résultats :
import matplotlib.pyplot as plt
plt.subplot(221)
plt.imshow(fonction(premier_grid, deuxieme_grid).T, extent=(0,1,0,1), origin='lower')
plt.plot(points[:,0], points[:,1], 'k.', ms=1)
plt.title('Original')
plt.subplot(222)
plt.imshow(premier_grid.T, extent=(0,1,0,1), origin='lower')
plt.title('Nearest')
plt.subplot(223)
plt.imshow(deuxieme_grid.T, extent=(0,1,0,1), origin='lower')
plt.title('Linear')
plt.subplot(224)
plt.imshow(troisieme_grid.T, extent=(0,1,0,1), origin='lower')
plt.title('Cubic')
plt.gcf().set_size_inches(6, 6)
plt.show()
Résultat de l’exécution :
Fonction interp2d :
x, y et z sont des tableaux de valeurs utilisées pour approcher une fonction f : z = f(x, y). Cette classe retourne une fonction dont la méthode d’appel utilise l’interpolation spline pour trouver la valeur des nouveaux points.
Si x et y représentent une grille régulière, pensez à utiliser RectBivariateSpline.
Exemple :
Nous allons construire une grille 2D et l’interpoler :
Syntaxe :
from scipy import interpolate
a = np.arange(-5.01, 5.01, 0.25)
b = np.arange(-5.01, 5.01, 0.25)
aa, bb = np.meshgrid(a,b)
c = np.sin(aa**2+bb**2)
f = interpolate.interp2d(a, b, c, kind='cubic')
import matplotlib.pyplot as plt
nouveau_a = np.arange(-5.01, 5.01, 1e-2)
nouveau_b = np.arange(-5.01, 5.01, 1e-2)
nouveau_c= f(nouveau_x, nouveau_y)
plt.plot(a, c[0, :], 'ro-', nouveau_x, nouveau_c[0, :], 'b-')
plt.show()
Résultat d’exécution :
Interpolation avec la fonction radial basis :
La fonction de base radiale est une fonction définie correspondant à un point de référence fixe .La fonction Rbf() prend également xs et ys comme arguments et produit une fonction exécutable qui peut être appelée avec de nouveaux xs .
Exemple :
Interpolez-en suivant xs et ys en utilisant rbf et trouvez les valeurs pour 2.1, 2.2 .... 2.9 :
Syntaxe :
import numpy as np
from scipy.interpolate import Rbf
a = np.arange(9)
b= a**2 + np.sin(a) + 1
fonct_inter = Rbf(a, b)
nouveau_tab = fonct_inter(np.arange(3.1, 4, 0.1))
print (nouveau_tab)
Résultat de l’exécution :
Exercices :
Exercice 1 :
Enoncé :
Ecrivez un programme qui interpole des points a=np.arrange(0,10) et b=exp (-a/3.0) .
Correction :
import matplotlib.pyplot as plt
from scipy import interpolate
a = np.arange(0,10)
b = np.exp(-a/3.0)
funct = interpolate.interp1d(a,b)
a_nouveau = np.arange(0, 9, 0.1)
b_nouveau = funct (a_nouveau) # utiliser la fonction d’interpolation retournée par « interp1d
plt.plot (a, b, 'o', a_nouveau, b_nouveau, '-')
plt.show()
Résultat de l’exécution :
Exercice 2 :
Enoncé : interpolation 1D
Dans cet exercice, on veut interpoler de 5 manières différentes des points :
Les a et b sont calculés selon les formules suivantes :
a= 5 points régulièrement espacés entre -1 et 1 .
b= (a-1)*((a-0.5)*a+0.5)
L’interpolation doit se faire selon 5 méthodes du paramètre kind de la fonction interp1d :
Zero , linear , quadratic ou cubic .
Vous devez biensur dessiner les fonctions d’interpolation afin d’interpréter les résultats des différentes interpolations.
Correction :
import pylab as pl
from scipy.interpolate import interp1d
import numpy as np
a = np.linspace(-1, 1, num=5)
# 5 points regulierement espaces entre -1 et 1.
b = (a-1.)*((a-0.5)*a+0.5)
# x et y sont des tableaux numpy
interpolation_0 = interp1d(x,y, kind='zero')
interpolation_1 = interp1d(x,y, kind='linear')
interpolation_2 = interp1d(x,y, kind='quadratic')
interpolation_3 = interp1d(x,y, kind='cubic')
interpolation_4 = interp1d(x,y, kind='nearest')
x_nouveau = np.linspace(-1, 1, num=40)
y_nouveau = (x_nouveau-1.)*(x_nouveau-0.5)*(x_nouveau+0.5)
pl.plot(x, y,'D',x_nouveau,interpolation_0(x_nouveau),':', x_nouveau, interpolation_2(x_nouveau),'-.',
x_nouveau,interpolation_3(x_nouveau),'-.',x_nouveau ,f3(x_nouveau),'s--',
x_nouveau,f4(x_nouveau),'--',x_nouveau, y_nouveau, linewidth=2)
pl.legend(['data','zero','linear','quadratic',
'cubic','nearest','exact'],loc='best')
pl.show()
Résultat de l’exécution :
Exercice 3 :
Enoncé :
Dans cet exercice, nous allons faire une interpolation 2D en utilisant la fonction interp2d() avec les 3 différents méthodes du paramètre kind :
Vous devez tout d’abord initier une grille de taille 20x20 . Ensuite initialiser le champ avec la fonction np.mgrid . Puis créer les différentes grilles d’interpolation avec les paramètres ‘linear’ , ‘cubic’ et ‘quantic’ .
Correction :
from scipy.interpolate import interp2d
import numpy as np
import matplotlib.pyplot as plt
a,b=np.mgrid[0:1:20j,0:1:20j]
#créer la grille de taille 20x20
c=np.cos(4*np.pi*a)*np.sin(4*np.pi*b )
# initialiser le champ
A,B=np.mgrid[0:1:100j,0:1:100j]
# créer la grille d’interpolation 100x100
interpolation_1=interp2d(a,b,c,kind='linear')
interpolation_2=interp2d(a,b,c,kind='cubic')
interpolation_3=interp2d(a,b,c,kind='quintic')
pl.figure(1)
pl.subplot(221) # Afficher les données originaux
pl.contourf (a,b,c)
pl.title('20x20')
pl.subplot(222) # Affichage l’interpolation linéaire
pl.contourf (A, B, interpolation_1 (A [:,0], B [0, :]))
pl.title('interpolation lineaire')
pl.subplot(223) # Affichage de l'interpolation cubique
pl.contourf (A, B, interpolation_2 (A [:,0], B [0, :]))
pl.title('interpolation cubic')
pl.subplot(224) # Affichage l’interpolation quintic
pl.contourf (A, B, interpolation_3 (A [:,0], B [0, :]))
pl.title ('interpolation quintic')
plt.show ()
Résultat de l’exécution :
Conclusion :
Nous sommes arrivés à la fin de ce tutoriel, nous supposons que maintenant la notion d’interpolation est très claire pour vous. Vous connaissez maintenant les différents types d’interpolation et les différentes méthodes déployés.
Il est très conseillé de refaire les différents exemples et exercices ainsi que de coder vos propres exemples.
Finalement, scipy est un module très riche et contient d’autres fonctionnalités qu’on verra dans les prochains tutoriels.
Vous êtes sur la bonne route, continuez ainsi. Bon courage et à prochain tutoriel chers lecteurs.
Article publié le 04 Novembre 2020 par Mouna HAMIM