On a des résultats de mesures et on sait qu'on doit avoir une relation
quadratique entre x et y :
Comment trouver ces 3 coefficients ?
Bien sûr on va faire une analyse en composante principale mais attention, cela
ne marche que pour les relations linéaires (ca nous donne un vecteur). Aussi
il faut introduire une nouvelle variable pour que notre équation soit linéaire.
Comment écrire notre problème pour qu'elle soit linéaire suivant 2 variables ?
On définit
Fabriquer un nuage de point 3D avec nos 3 variables en choisissant les inconnues
comme indiqué dans l'équation ci-dessous :
N = 50
x = 6 * np.random.rand(N) - 3
nuage = np.array(...)
fig = go.Figure(data=[go.Scatter3d(x=nuage[0,:], y=nuage[1,:], z=nuage[2,:], mode='markers')])
N = 50
x = 6 * np.random.random(N) - 3 # x varie entre -3 et 3
z = -1.3 * np.square(x) + 0.2 * x + 1.45 + (2*np.random.random(N) - 1)
nuage = np.array([x,z])
plt.plot(nuage[0], nuage[1], 'x')
plt.title('Un nuage de points')
plt.axis('equal');
Fabriquer à partir de notre nuage de points 2D un nuage de points 3D en introduisant la nouvelle variable qu'on a choisit.
Le nouveau nuage s'appelle nuage3D.
y = np.square(nuage[0])
nuage3D = np.array([x,y,z])
fig = go.Figure(data=[go.Scatter3d(x=nuage3D[0], y=nuage3D[1], z=nuage3D[2], mode='markers')])
fig.show()fig = go.Figure(data=[go.Scatter3d(x=nuage3D[0], y=nuage3D[1], z=nuage3D[2], mode='markers')])
fig.show()
Calculer la matrice de covariance de notre nuage et ses vecteurs propres (on stockera les vecteurs propres dans la variable vec).
cov = np.cov(nuage3D.copy())
array([[ 2.723, -0.146, 0.649],
[-0.146, 7.802, -9.982],
[ 0.649, -9.982, 13.184]])
val, vec = lin.eig(cov)
[20.852+0.j 2.733+0.j 0.124+0.j]
[[ 0.033 -0.994 -0.107]
[-0.607 -0.106 0.787]
[ 0.794 -0.039 0.607]]
# On trie suivant la norme des valeurs propres par ordre décroissant (ce n'est pas trié par défaut)
idx = np.argsort(val)[::-1]
val = val[idx]
vec = vec.T[idx].T # ce sont les colonnes qu'il faut ordonner et non les lignes
print(val, '\n', vec)
[20.852+0.j 2.733+0.j 0.124+0.j]
[[ 0.033 -0.994 -0.107]
[-0.607 -0.106 0.787]
[ 0.794 -0.039 0.607]]
fig = go.Figure(data=[go.Scatter3d(x=nuage3D[0], y=nuage3D[1], z=nuage3D[2], mode='markers'),
go.Scatter3d(x=[0,-5*vec[0,0]], y=[0,-5*vec[1,0]], z=[0,-5*vec[2,0]]),
go.Scatter3d(x=[0,vec[0,1]], y=[0,vec[1,1]], z=[0,vec[2,1]])])
fig.show()
Que peut-on déduire de notre premier vecteur propre ?
Il nous donne la direction principale du nuage de point. En regardant bien la figure on voit que le vecteur dépend de y mais pas de x donc il nous donne la composante de y (c.a.d. celle de x²).
alpha = vec[2,0] / vec[1,0] # la pente du premier vecteur propre
-1.3064566708285197
Créer un nuage de point en 2D qui ne prend plus en compte l'impact du coefficient que l'on vient de trouver.
On appelle ce nouveau nuage nuage2D (ce n'est pas le même que notre nuage initial).
nuage2D = np.array([nuage3D[0], nuage3D[2] - alpha * nuage3D[1]])
plt.plot(nuage2D[0], nuage2D[1], 'x')
plt.axis('equal');
Que peut-on en déduire ?
cov = np.cov(nuage2D.copy())
array([[2.723, 0.459],
[0.459, 0.419]])
val, vec = lin.eig(cov)
[2.811+0.j 0.331+0.j]
[[ 0.982 -0.188]
[ 0.188 0.982]]
Donner les valeurs de
beta = vec[1,0] / vec[0,0]
0.1916825747224307
moyenne = nuage2D.mean(axis=1)
print('Moyenne des points du nuage :', moyenne)
eq_droite = lambda x: beta * (x - moyenne[0]) + moyenne[1]
print("Le décalage verticale est de ", eq_droite(0))
gamma = eq_droite(0)
Moyenne des points du nuage : [0.228 1.328]
Le décalage verticale est de 1.2847052624609907
print("Les coefficients de z fonction polynomiale de degré 2 en x sont :\n")
print(f"alpha = {alpha}")
print(f"beta = {beta}")
print(f"gamma = {gamma}")
Les coefficients de z fonction polynomiale de degré 2 en x sont :
alpha = -1.3064566708285197
beta = 0.1916825747224307
gamma = 1.2847052624609907