# CAMA : ma06 Vecteurs propres -- Exercice: nuage de points en 3D # 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 ? :::spoiler 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.} $$ ```python= N = 50 x = 6 * np.random.rand(N) - 3 nuage = np.array(...) ``` ```python= fig = go.Figure(data=[go.Scatter3d(x=nuage[0,:], y=nuage[1,:], z=nuage[2,:], mode='markers')]) ``` :::spoiler Solution ```python= 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]) ``` ```python= plt.plot(nuage[0], nuage[1], 'x') plt.title('Un nuage de points') plt.axis('equal'); ``` ![](https://i.imgur.com/dO2QHIo.png) ::: ## 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. :::spoiler Solution ```python= y = np.square(nuage[0]) nuage3D = np.array([x,y,z]) ``` ```python= 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() ``` ![](https://i.imgur.com/s3DPorJ.png) ::: ## Matrice de covariance Calculer la matrice de covariance de notre nuage et ses vecteurs propres (on stockera les vecteurs propres dans la variable vec). :::spoiler Solution ```python= cov = np.cov(nuage3D.copy()) ``` ``` array([[ 2.723, -0.146, 0.649], [-0.146, 7.802, -9.982], [ 0.649, -9.982, 13.184]]) ``` ```python= 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]] ``` ```python= # 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]] ``` ```python= 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() ``` ![](https://i.imgur.com/5FF5DbW.png) ::: ## Vecteur propre Que peut-on déduire de notre premier vecteur propre ? :::spoiler 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²). ```python= alpha = vec[2,0] / vec[1,0] # la pente du premier vecteur propre ``` ``` -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. :::spoiler Solution On appelle ce nouveau nuage nuage2D (ce n'est pas le même que notre nuage initial). ```python= nuage2D = np.array([nuage3D[0], nuage3D[2] - alpha * nuage3D[1]]) ``` ```python= plt.plot(nuage2D[0], nuage2D[1], 'x') plt.axis('equal'); ``` ![](https://i.imgur.com/dzJ7oHF.png) ::: ## Deduction Que peut-on en déduire ? :::spoiler Solution ```python= cov = np.cov(nuage2D.copy()) ``` ``` array([[2.723, 0.459], [0.459, 0.419]]) ``` ```python= val, vec = lin.eig(cov) ``` ``` [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. :::spoiler Solution ```python= beta = vec[1,0] / vec[0,0] ``` ``` 0.1916825747224307 ``` ```python= 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 ``` ```python= 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 ``` :::