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
|
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
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
|