[PYTHON] [Mathématiques] Visualisons ce que sont les valeurs propres et les vecteurs propres

Le concept de ** valeur propre ** apparaît en algèbre linéaire. Je pense que c'est difficile à imaginer au début, mais c'est un concept important et souvent utilisé dans les statistiques, alors j'aimerais essayer de l'expliquer en écrivant un graphique d'animation comme cette série de visualisation.

Je comprendrai la signification d'un tel graphique. _eigen_value-compressor-2.gif

1. Que sont les valeurs propres et les vecteurs propres?

Tout d'abord, que sont les valeurs propres et les vecteurs propres? Il est comme suit lorsqu'il est exprimé par une formule mathématique.


A{\bf x} = \lambda {\bf x}

$ {\ bf x} $ in $ {\ bf x} \ neq {\ bf 0} $, multiplié par la matrice A, de sorte que la longueur soit $ \ lambda $ fois $ {\ bf x} $ Les choses sont appelées ** vecteurs propres ** et $ \ lambda $ sont appelées ** valeurs propres **. Qui ne sait pas? ?? ?? Donc, je ne suis pas sûr de cela seul. Je voudrais l'expliquer avec une explication graphique immédiatement.

2. Transformation linéaire par la matrice A

Avant d'expliquer les valeurs propres et les vecteurs propres, examinons la transformation linéaire par matrice. Par exemple, supposons que la matrice $ A $ soit une matrice dont les composants sont les suivants.

A = 
\left[
\begin{array}{cc}
2 & 1 \\
-0.5 & -1.5 \\
\end{array}
\right]

À ce stade, si vous calculez $ Axe $


A{\bf x} = \left[
\begin{array}{cc}
2 & 1 \\
-0.5 & -1.5 \\
\end{array}
\right]
\left[
\begin{array}{cc}
x_1 \\
x_2 \\
\end{array}
\right]
=
\left[
\begin{array}{cc}
2x_1 + x_2 \\
-0.5x_1 - 1.5x_2 \\
\end{array}
\right]

Et sera. Si $ {\ bf x} = (1, 1) $

A{\bf x} = \left[
\begin{array}{cc}
2 & 1 \\
-0.5 & -1.5 \\
\end{array}
\right]
\left[
\begin{array}{cc}
1 \\
1 \\
\end{array}
\right]
=
\left[
\begin{array}{cc}
2 + 1 \\
-0.5 - 1.5 \\
\end{array}
\right]
=
\left[
\begin{array}{cc}
3 \\
-2 \\
\end{array}
\right]

Sera.

Multiplier la matrice $ A $ par $ {\ bf x} = (1, 1) $ donne $ (3, -2) $. Pour illustrer cela,

eigen_val02-compressor.png

Avec ce sentiment, le vecteur bleu $ (1, 1) $ est tourné et étiré. Donc, je pense que l'opération de multiplication de cette matrice peut être considérée comme ** "faire pivoter et étirer le vecteur" **.

Vérifions avec le code Python pour voir si ce sera le même même s'il est correctement calculé. En regardant le graphique des résultats,

eigen_val07-compressor.png

Avec ce sentiment, la ligne bleue partant de l'origine est le vecteur (1, 1), mais vous pouvez voir que la ligne rouge après la conversion s'étend jusqu'à (3, -2). Le code est ci-dessous.

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation as ani

plt.figure(figsize=(8,8))
n=20

A = [[ 2, 1],
     [-0.5,-1.5]]
x = [1, 1]

a = np.dot(A, x)   #Je calcule Axe ici

plt.plot([0, x[0]], [0, x[1]], "b", zorder=100)
plt.plot([0, a[0]], [0, a[1]], "r", zorder=100)

plt.plot([-15,50],[0,0],"k", linewidth=1)
plt.plot([0,0],[-40,40],"k", linewidth=1)
plt.xlim(-1,4)
plt.ylim(-3,2)
plt.show()

De même, tracez 100 points dans une zone carrée et transformez-la avec la matrice $ A $ pour la transformer en quadrilatère parallèle. Chaque point du carré bleu s'est déplacé vers un point quadrilatéral parallèle rouge.

eigen_val04-compressor.png

Je l'ai tracé numériquement afin que la correspondance entre les points bleus et les points rouges puisse être facilement comprise.

eigen_val05-compressor.png

Voici le code pour dessiner le graphique ci-dessus.

plt.figure(figsize=(10,10))
n=10
xmin = -5
xmax =  35
ymin = -20
ymax =  10

A = [[ 2, 1],
     [-0.5,-1.5]]
for i in range(n):
    for j in range(n):
        x=j
        y=i
        
        a = np.dot(A, [x, y])
        
        plt.scatter(x,  y,  facecolor="b", edgecolors='none', alpha=.7, s=20)
        plt.scatter(a[0], a[1], facecolor="r", edgecolors='none', alpha=.7)

        plt.plot([xmin,xmax],[0,0],"k", linewidth=1)
        plt.plot([0,0],[ymin,ymax],"k", linewidth=1)
        plt.xlim(xmin, xmax)
        plt.ylim(ymin, ymax)
plt.show()
plt.figure(figsize=(10,10))
n=10
xmin = -5
xmax =  35
ymin = -20
ymax =  10

A = [[ 2, 1],
     [-0.5,-1.5]]
for i in range(n):
    for j in range(n):
        x=j
        y=i

        a = np.dot(A, [x, y])
        
        loc_adjust = .2  #Réglage de la position d'affichage
        plt.text(x-loc_adjust, y-loc_adjust, "%d"%(i*n + j), color="blue")
        plt.text(a[0]-loc_adjust, a[1]-loc_adjust, "%d"%(i*n + j), color="red")

        plt.plot([xmin,xmax],[0,0],"k", linewidth=1)
        plt.plot([0,0],[ymin,ymax],"k", linewidth=1)
        plt.xlim(xmin, xmax)
        plt.ylim(ymin, ymax)
plt.show()

3. Visualisation des valeurs propres et des vecteurs propres

Sur la base de la section précédente, la formule valeur propre / vecteur propre,

A{\bf x} = \lambda {\bf x}

Est une combinaison de A et $ {\ bf x} $ qui ne tourne pas même si elle est convertie par la matrice A, mais qui ne s'étire que de sorte que seule la longueur change, comme indiqué dans le graphique ci-dessous. est.

eigen01-compressor.png

Faisons une animation. Tout d'abord, préparez un vecteur de longueur 1 (ligne bleue) en tant que vecteur avant la conversion et faites-le pivoter de 360 degrés. Dessinez un vecteur (ligne rouge) transformé linéairement par la matrice A pour chacun. Le moment où ces deux lignes s'alignent en ligne droite est celui où la valeur propre et le vecteur propre correspondent. La ligne bleue $ {\ bf x} $ et la ligne rouge $ A {\ bf x} $ pointent dans la même direction et diffèrent par la longueur, c'est-à-dire $ A {\ bf x} = \ lambda {\ bf x} $ est.

Par souci de clarté, les lignes sont épaissies lorsqu'elles sont alignées en ligne droite.

_eigen_value-compressor-2.gif

Vous pouvez calculer les valeurs propres et les vecteurs propres avec numpy, alors essayons-le.

la, v = np.linalg.eig(A)
print "la",la
print "v",v

Le résultat est ci-dessous.

output


la [ 1.85078106 -1.35078106]
v [[ 0.98904939 -0.28597431]
   [-0.1475849   0.95823729]]

Deux valeurs propres $ \ lambda_1 = 1.85078106, \ lambda_2 = -1.35078106 $ et deux vecteurs propres $ x_1 = (0.98904939, -0.1475849), x_2 = (-0.28597431, 0.95823729) $ ont été obtenus. Supprimons une image de l'animation précédente et comparons-la. La partie de titre "original (bleu): (-0,989, -0,149)" est presque la même que $ x_1 $. La légère erreur est due à la fréquence d'images approximative de l'animation, qui est plus cohérente avec des fréquences plus élevées (plus de précision). Aussi, "[length] red: 1.849", qui correspond également à $ \ lambda_1 $: smile:

eigen_val11-compressor.png

Ainsi, en deux dimensions, le vecteur propre est un vecteur dans lequel la direction ne change pas et seule la longueur change lorsque vous essayez un vecteur dans toutes les directions à 360 degrés de l'origine. On peut dire que la valeur propre est le rapport de la longueur du vecteur avant et après conversion dans le vecteur dans cette direction: blush:

4. Exemple d'application dans les statistiques

Je voudrais donner un exemple dans lequel les valeurs propres et les vecteurs propres sont utilisés dans les statistiques. Jetez d'abord un œil à ce graphique.

eigen_val10-compressor.png

Le point bleu ci-dessus est un tracé de 1000 nombres aléatoires qui suivent une distribution normale bidimensionnelle. Si vous calculez la matrice de co-distribution de distribution à partir de ces données, vous obtiendrez une matrice 2x2. Le calcul des vecteurs propres de cette matrice donne deux vecteurs propres bidimensionnels. Si vous en mettez deux côte à côte, vous pouvez à nouveau créer une ligne. Le graphique des points rouges ci-dessous est un tracé des données générées en appliquant une matrice de ces vecteurs propres à l'origine des données originales. La conversion est comme si le côté le plus long de l'ellipse était amené horizontalement en le faisant pivoter sans changer la forme des données. Cette opération, en fait, devient une méthode d'analyse appelée analyse en composantes principales dans le monde de la statistique. (L'article sur l'analyse des composants principaux est ici)

De cette manière, l'idée de valeurs propres et de vecteurs propres est également utilisée dans le domaine des statistiques.

Vous trouverez ci-dessous le code Python pour cette opération.

np.random.seed(0)
xmin = -10
xmax =  10
ymin = -10
ymax =  10

#moyenne
mu = [2,2]
#Co-distribué
cov = [[3,2.3],[1.8,3]]

#Génération de nombres aléatoires à distribution normale bivariée
x, y = np.random.multivariate_normal(mu,cov,1000).T

av_x = np.average(x)
av_y = np.average(y)

#Calculer la matrice de co-distribution de distribution à partir des données
S = np.cov(x, y)
print "S", S
    
#Calculer la valeur propre et le vecteur propre
la, v = np.linalg.eig(S)

print "la", la
print "v", v

#Faites glisser pour que l'origine soit au centre
x2 = x - av_x
y2 = y - av_y

#Multipliez les données qui font glisser l'origine par une matrice créée en organisant des vecteurs propres.
a1 = np.array([np.dot(v, [x2[i],y2[i]]) for i in range(len(x))])

#Dessiner un graphique
plt.figure(figsize=(8, 13))

#Graphique des données d'origine
plt.subplot(211)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.scatter(x, y, alpha=0.5, zorder=100)
plt.plot([0, 0], [ymin, ymax], "k")
plt.plot([xmin, xmax], [0, 0], "k")

#Tracé de données multiplié par une matrice créée en organisant des vecteurs propres
plt.subplot(212)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.scatter(a1[:,0], a1[:,1], c="r", alpha=0.5, zorder=100)
plt.plot([0, 0], [ymin, ymax], "k")
plt.plot([xmin, xmax], [0, 0], "k")
plt.show()

output


S [[ 2.6774093   1.93221432]
   [ 1.93221432  3.05844013]]
la [ 0.92634075  4.80950869]
v [[-0.74098708 -0.67151928]
   [ 0.67151928 -0.74098708]]

Si vous calculez la formule matricielle de v, ce sera 1, vous pouvez donc voir que cette conversion tourne uniquement et que la longueur ne change pas.

Tout le code Python pour cet article peut être trouvé ici [https://gist.github.com/matsuken92/47e5bf7b49e01f8a4a9d).

Recommended Posts

[Mathématiques] Visualisons ce que sont les valeurs propres et les vecteurs propres
Trouver valeur propre / vecteur propre
[Python] Que sont @classmethod et les décorateurs?
(Débutant) Que sont les cœurs et les threads?
Valeurs authentiques et vecteurs propres: Algèbre linéaire en Python <7>
Que sont les vendeurs de go mod, go get and go?
Que sont les options Linux POSIX et GNU?
Données d'entraînement et données de test (Que sont X_train et y_train?) ②
Que comparez-vous avec Python et ==?
Que sont les taples et * args python après tout?