[Python] PCA scratch dans l'exemple de "Introduction à la méthode d'analyse multivariée"

introduction

J'ai essayé de suivre la preuve de l'analyse en composantes principales, mais je ne comprenais pas comment l'utiliser, j'ai donc décidé d'approfondir ma compréhension en grattant l'exemple 4 du chapitre 9 du livre "Introduction to Multivariate Analysis" publié par Science. Cet article est destiné à être ce rappel.

Quoi utiliser

・ VSCode (... eh bien, n'importe quel éditeur va bien) ・ Python version 3.7.0 ·Bibliothèque -Numpy (pour gérer la matrice) -Matplotlib (utilisé dans le diagramme de dispersion) ・ Introduction à la méthode d'analyse multivariée (Science) ← Dans ce qui suit, ce livre sera appelé un manuel.

couler

Vérifiez facilement la politique de scratch. ① Saisie des données ② Standardisation des données ③ Calculez la matrice des coefficients de corrélation ④ Calculer la valeur propre et le vecteur propre ⑤ Effectuer l'analyse des composants principaux et compresser en 2 dimensions ⑥ De plus, le facteur de charge est également indiqué. ⑦ Dessinez un diagramme de dispersion de chaque chargement factoriel et du score de la composante principale

Matrice de données

Les données de l'exemple, je les ai saisies à la main.

ex9_4.txt


86 79 67 68
71 75 78 84
42 43 39 44
62 58 98 95
96 97 61 63
39 33 45 50
50 53 64 72
78 66 52 47
51 44 76 72
89 92 93 91

code

Je vais mettre le code.

scratch.py


import numpy as np
import numpy.linalg as LA
import matplotlib.pyplot as plt

#Entrez la taille de l'échantillon(ligne)
n = int(input())

#Entrer des données
a = [input().split() for l in range(n)]
data = np.array(a, dtype=float)
line = int(data.shape[0])
row = int(data.shape[1])
print(line, row)

means = np.empty(row)
sds = np.empty(row)

#Calculer la moyenne
sum = 0
for i in range(row):
    for j in range(line):
        sum +=  data[j][i]
    else:
        means[i] = sum / line
        sum = 0
print("moyenne:")
print(means)

#Calculer l'écart type
for i in range(row):
    for j in range(line):
        sum += (data[j][i]-means[i]) ** 2
    else:
        sds[i] = (sum / (line - 1)) ** 0.5
        sum = 0
print("écart-type:")
print(sds)

#Standardisation
standardized_data = np.zeros((line,row))
for i in range(row):
    for j in range(line):
        standardized_data[j][i] = (data[j][i] - means[i]) / sds[i]  
print(standardized_data)

#Calculer la matrice des coefficients de corrélation
cc_matrix = np.zeros((row, row))
for i in range(row):
    for j in range(row):
        if(cc_matrix[i][j] == 0):
            for k in range(line):
                sum += standardized_data[k][i] * standardized_data[k][j]
            else:
                cc_matrix[i][j] = sum / (line - 1)
                cc_matrix[j][i] = cc_matrix[i][j]
                sum = 0

#Problème de valeur unique
w,v = LA.eig(cc_matrix)
#print(w)
#print(v)

#Compression en 2 dimensions par analyse en composantes principales
main_component = np.zeros((line, 2))
z_1, z_2 = 0, 0
for i in range(line):
    for j in range(row):
        z_1 += standardized_data[i][j] * v[j][0]
        z_2 += standardized_data[i][j] * v[j][1]
    else:
        main_component[i][0] = z_1
        main_component[i][1] = z_2
        z_1, z_2 = 0, 0
print("Composant principal:")
print(main_component)

#Facteur de chargement
factor_load = np.zeros((2, row))
for i in range(2):
    for j in range(row):
        factor_load[i][j] = (w[i] ** 0.5) * v[j][i]
print("Facteur de chargement:")
print(factor_load)

#Dessinez un diagramme de dispersion

#Diagramme de dispersion du chargement factoriel
for label in range(row):
    plt.scatter(factor_load[0][label], factor_load[1][label], marker="$"+str(label+1)+"$")
    plt.title('factor_load')
    plt.xlabel('pc1')
    plt.ylabel('pc2')
plt.show()

#Diagramme de dispersion des scores des composants principaux
for label in range(line):
    plt.scatter(main_component[label][0], main_component[label][1], marker="$"+str(label+1)+"$")
    plt.title('principal component')
    plt.xlabel('pc1')
    plt.ylabel('pc2')
plt.show()

Chaque processus du code est expliqué ci-dessous.

Saisie des données

Tout d'abord, utilisez input () pour saisir le nombre de lignes de la matrice à créer à partir du clavier. Il s'agit de la taille de l'échantillon dans les données d'origine. Ensuite, saisissez les données de la matrice avec le clavier et gérez-les avec numpy. Je pense qu'il existe une autre bonne méthode pour cette méthode de saisie (mais cette fois, cette partie est comparée à l'analyse des composants principaux cibles. Je pensais que c'était une question triviale, et je ne voulais pas passer trop de temps, alors j'ai décidé de le mettre sur l'étagère et de continuer.) Ensuite, obtenez le nombre de lignes et de colonnes de la matrice créée. Ces types l'utilisent beaucoup. De plus, avec ce code, le vecteur moyen et le vecteur d'écart type sont initialisés à ce stade.


#Entrez la taille de l'échantillon(ligne)
n = int(input())

#Entrer des données
a = [input().split() for l in range(n)]
data = np.array(a, dtype=float)
line = int(data.shape[0])
row = int(data.shape[1])
print(line, row)

means = np.empty(row)
sds = np.empty(row)

Standardisation des données

À partir de la matrice de données, trouvez la moyenne et l'écart type de chaque colonne et utilisez-les pour créer une matrice qui standardise les données d'origine. (Standardized_data) À partir de là, c'est essentiellement une tempête de phrases, j'ai beaucoup utilisé ma tête en indice. Notez également que lors du calcul de l'écart type, le nombre à diviser doit être n-1 au lieu de n, sinon la valeur ne sera pas celle du manuel.


#Calculer la moyenne
sum = 0
for i in range(row):
    for j in range(line):
        sum +=  data[j][i]
    else:
        means[i] = sum / line
        sum = 0
print("moyenne:")
print(means)

#Calculer l'écart type
for i in range(row):
    for j in range(line):
        sum += (data[j][i]-means[i]) ** 2
    else:
        sds[i] = (sum / (line - 1)) ** 0.5
        sum = 0
print("écart-type:")
print(sds)

#Standardisation
standardized_data = np.zeros((line,row))
for i in range(row):
    for j in range(line):
        standardized_data[j][i] = (data[j][i] - means[i]) / sds[i]  
print(standardized_data)

Calculer la matrice des coefficients de corrélation

Nous apprécions les équations du manuel (9.2) et (9.3) et calculons la matrice des coefficients de corrélation. Bien entendu, nous confirmons la preuve sur papier avant d'utiliser les équations. De plus, nous essayons de réduire la quantité de calcul en utilisant le fait que la matrice des coefficients de corrélation est une matrice symétrique.

#Calculer la matrice des coefficients de corrélation
cc_matrix = np.zeros((row, row))
for i in range(row):
    for j in range(row):
        if(cc_matrix[i][j] == 0):
            for k in range(line):
                sum += standardized_data[k][i] * standardized_data[k][j]
            else:
                cc_matrix[i][j] = sum / (line - 1)
                cc_matrix[j][i] = cc_matrix[i][j]
                sum = 0

Problème de valeur unique

Je vais calculer la valeur propre, le vecteur propre ... mais je ne pouvais pas penser à comment gratter ici, alors j'ai décidé de le jeter dans la fonction linalg.eig et de continuer.Je mets la valeur propre dans w et le vecteur propre dans v. Masu. Si vous avez un bon moyen de gratter ici, faites-le moi savoir.

#Problème de valeur unique
w,v = LA.eig(cc_matrix)
#print(w)
#print(v)

Enfin l'analyse des composants principaux

C'est le sujet principal Cette fois, je veux vérifier le flux jusqu'au diagramme de dispersion, j'ai donc décidé de supprimer deux dimensions, c'est-à-dire deux composants principaux, et j'ai écrit le code. car la déclaration est difficile ...


#Compression en 2 dimensions par analyse en composantes principales
main_component = np.zeros((line, 2))
z_1, z_2 = 0, 0
for i in range(line):
    for j in range(row):
        z_1 += standardized_data[i][j] * v[j][0]
        z_2 += standardized_data[i][j] * v[j][1]
    else:
        main_component[i][0] = z_1
        main_component[i][1] = z_2
        z_1, z_2 = 0, 0
print("Composant principal:")
print(main_component)

Facteur de chargement

En passant, c'est un facteur de chargement.


#Facteur de chargement
factor_load = np.zeros((2, row))
for i in range(2):
    for j in range(row):
        factor_load[i][j] = (w[i] ** 0.5) * v[j][i]
print("Facteur de chargement:")
print(factor_load)

Nuage de points

Je vais tracer le score de la composante principale et la quantité de chargement de facteur sur lesquels j'ai travaillé dur sur le diagramme de dispersion. L'axe des x est le premier composant principal et l'axe des y est le deuxième composant principal.

#Dessinez un diagramme de dispersion

#Diagramme de dispersion du chargement factoriel
for label in range(row):
    plt.scatter(factor_load[0][label], factor_load[1][label], marker="$"+str(label+1)+"$")
    plt.title('factor_load')
    plt.xlabel('pc1')
    plt.ylabel('pc2')
plt.show()

#Diagramme de dispersion des scores des composants principaux
for label in range(line):
    plt.scatter(main_component[label][0], main_component[label][1], marker="$"+str(label+1)+"$")
    plt.title('principal component')
    plt.xlabel('pc1')
    plt.ylabel('pc2')
plt.show()

Nuage de points

load.png main_component.png J'ai pu dessiner à peu près la même chose qu'un manuel. Est-ce bien

À la fin

J'ai écrit un article sur la qiita pour la première fois, je pense qu'il y a beaucoup de choses difficiles à lire. Aussi, parce que je suis immature, je pense qu'il y a beaucoup de tsukkomi dans le code ci-dessus. Je suis très bienvenu à tsukkomi pour eux. Plutôt, je l'ai posté sur qiita pour obtenir tsukkomi.

Les références

Yasushi Nagata, Masahiko Muchinaka Introduction to Multivariate Analysis Method Science, 10 avril 2001

Recommended Posts

[Python] PCA scratch dans l'exemple de "Introduction à la méthode d'analyse multivariée"
De l'introduction de JUMAN ++ à l'analyse morphologique du japonais avec Python
[Introduction à Python] Une explication approfondie des types de chaînes de caractères utilisés dans Python!
Un exemple de réponse à la question de référence de la session d'étude. Avec python.
Comment obtenir le nombre de chiffres en Python
Reproduire l'exemple d'exécution du chapitre 4 de Hajipata en Python
[Introduction à Python] Utilisation basique de la bibliothèque matplotlib
Reproduire l'exemple d'exécution du chapitre 5 de Hajipata en Python
Pour faire l'équivalent de Ruby ObjectSpace._id2ref en Python
[Python] Comment faire PCA avec Python
Dans la commande python, python pointe vers python3.8
Introduction à l'analyse d'image opencv python
Comment déterminer l'existence d'un élément sélénium en Python
Comment connaître la structure interne d'un objet en Python
Introduction aux bases de Python de l'apprentissage automatique (apprentissage non supervisé / analyse principale)
Comment vérifier la taille de la mémoire d'une variable en Python
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
N'hésitez pas à changer l'étiquette de légende avec Seaborn en python
J'ai écrit le code pour écrire le code Brainf * ck en python
[Introduction à Python] Comment utiliser l'opérateur in dans l'instruction for?
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
[Introduction à Python] Comment utiliser la classe en Python?
Vérifiez le comportement du destroyer en Python
Théorie générale de la relativité en Python: Introduction
"Un livre pour former des compétences en programmation pour combattre dans le monde" Exemple de réponse au code Python --1.4 Séquence de phrases
Exemple d'analyse de squelette tridimensionnelle par Python
Le résultat de l'installation de python sur Anaconda
Principes de base pour exécuter NoxPlayer en Python
Chapitre 1 Introduction à Python Découpez uniquement les bons points de Deeplearning à partir de zéro
À la recherche du FizzBuzz le plus rapide en Python
Exemple pratique d'architecture hexagonale en Python
Introduction aux vecteurs: Algèbre linéaire en Python <1>
Introduction à la vérification de l'efficacité Chapitre 1 écrit en Python
[Introduction au Data Scientist] Bases de Python ♬
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
Je veux convertir par lots le résultat de "chaîne de caractères" .split () en Python
Je veux expliquer en détail la classe abstraite (ABCmeta) de Python
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
[Introduction à Python] Quelle est la méthode de répétition avec l'instruction continue?
"Livre pour former la capacité de programmation à se battre dans le monde" Exemple de réponse de code Python --1.9 Rotation de la chaîne de caractères
Introduction de Python
Comment utiliser la bibliothèque C en Python
Sortie du nombre de cœurs de processeur en Python
[Introduction à Udemy Python3 + Application] 26. Copie du dictionnaire
[Python] Trier la liste de pathlib.Path dans l'ordre naturel
Introduction à la vérification de l'efficacité Chapitre 3 écrit en Python
Résumé de la façon d'importer des fichiers dans Python 3
Récupérer l'appelant d'une fonction en Python
tse --Introduction à l'éditeur de flux de texte en Python
Faites correspondre la distribution de chaque groupe en Python
[Introduction à Udemy Python3 + Application] 19. Copie de la liste
Afficher le résultat du traitement de la géométrie en Python
Pour remplacer dynamiquement la méthode suivante en python
Copiez la liste en Python
J'ai écrit "Introduction à la vérification des effets" en Python
Résumé de l'utilisation de MNIST avec Python
Dessinez des graphiques dans Julia ... Laissez les graphiques à Python
Découvrez la fraction de la valeur saisie en python
Conseils pour rédiger un aplatissement concis en python