Home CAMA : ma06 Vecteurs propres -- Exercice: nuage de points en 3D
Post
Cancel

CAMA : ma06 Vecteurs propres -- Exercice: nuage de points en 3D

Lien de la note Hackmd

Cours du 30/03

On a des résultats de mesures et on sait qu’on doit avoir une relation quadratique entre x et y :

\[y = \alpha \, x^2 + \beta \, x + \gamma\]

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 ?

Solution

On définit $y=x^2$ et ainsi $z$ s’écrit en fonction de $x$ et $y$.

Données de l’expérience

Fabriquer un nuage de point 3D avec nos 3 variables en choisissant les inconnues comme indiqué dans l’équation ci-dessous :

\[y = -1.3 \, x^2 + 0.2 \, x + 1.45 + U(-1,1) \quad \textrm{avec U la loi uniforme qui simule du bruit.}\]
1
2
3
N = 50
x = 6 * np.random.rand(N) - 3
nuage = np.array(...)
1
fig = go.Figure(data=[go.Scatter3d(x=nuage[0,:], y=nuage[1,:], z=nuage[2,:], mode='markers')])
Solution
1
2
3
4
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])
1
2
3
plt.plot(nuage[0], nuage[1], 'x')
plt.title('Un nuage de points')
plt.axis('equal');

Calculs pour trouver les caractéristiques de notre nuage

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.

Solution
1
2
y = np.square(nuage[0])
nuage3D = np.array([x,y,z])
1
2
3
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()

Matrice de covariance

Calculer la matrice de covariance de notre nuage et ses vecteurs propres (on stockera les vecteurs propres dans la variable vec).

Solution
1
cov = np.cov(nuage3D.copy())
1
2
3
array([[ 2.723, -0.146,  0.649],
       [-0.146,  7.802, -9.982],
       [ 0.649, -9.982, 13.184]])
1
val, vec = lin.eig(cov)
1
2
3
4
[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]]
1
2
3
4
5
# 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)
1
2
3
4
[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]]
1
2
3
4
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()

Vecteur propre

Que peut-on déduire de notre premier vecteur propre ?

Solution

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²).

1
alpha = vec[2,0] / vec[1,0]     # la pente du premier vecteur propre
1
-1.3064566708285197

Nuage de point en 2D

Créer un nuage de point en 2D qui ne prend plus en compte l’impact du coefficient que l’on vient de trouver.

Solution

On appelle ce nouveau nuage nuage2D (ce n’est pas le même que notre nuage initial).

1
nuage2D = np.array([nuage3D[0], nuage3D[2] - alpha * nuage3D[1]])
1
2
plt.plot(nuage2D[0], nuage2D[1], 'x')
plt.axis('equal');

Deduction

Que peut-on en déduire ?

Solution
1
cov = np.cov(nuage2D.copy())
1
2
array([[2.723, 0.459],
       [0.459, 0.419]])
1
val, vec = lin.eig(cov)
1
2
3
[2.811+0.j 0.331+0.j]
[[ 0.982 -0.188]
 [ 0.188  0.982]]

Valeurs finales

Donner les valeurs de $\alpha, \beta, \gamma$ que vous avez trouvées à partir de votre nuage de point 3D initial.

Solution
1
beta = vec[1,0] / vec[0,0]
1
0.1916825747224307
1
2
3
4
5
6
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)
1
2
Moyenne des points du nuage : [0.228 1.328]
Le décalage verticale est de  1.2847052624609907
1
2
3
4
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}")
1
2
3
4
5
Les coefficients de z fonction polynomiale de degré 2 en x sont :

alpha = -1.3064566708285197
beta  = 0.1916825747224307
gamma = 1.2847052624609907
This post is licensed under CC BY 4.0 by the author.