Dans Publié la dernière fois, j'ai suivi les statistiques basées sur les mangas [Analyse factorielle] Analyse des composants principaux du chapitre 4 avec Python.
Cette fois, je vais contester l'analyse des composants principaux des données texte avec Python.
À l'origine, c'est ce livre d'analyse de texte de M. Akitetsu Kim qui m'a donné envie d'en savoir plus sur l'analyse en composantes principales. Lorsque j'ai voulu regrouper des données textuelles, j'ai trouvé que l'analyse en composantes principales de ce livre était intéressante, et c'était le déclencheur pour étudier l'analyse en composantes principales.
La cible de l'analyse est l'écriture de données écrites sur trois thèmes (amis, voitures, cuisine japonaise). Il y a 33 données au total pour 3 thèmes x 11 personnes.
Les données peuvent être obtenues à partir du téléchargement du code source sur la page d'assistance de ici.
Les données ne sont pas du texte, mais déjà au format Bag of Words (BoW). Par conséquent, le traitement tel que l'analyse morphologique et la conversion BoW n'est pas inclus cette fois.
Le code est détourné de Article précédent.
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'Noto Sans CJK JP']
#Lecture des données d'écriture * Veuillez modifier le chemin du fichier en fonction de votre environnement.
df = pd.read_csv('./sakubun3f.csv',encoding='cp932')
data = df.values
# "Words"Colonne,"OTHERS"Exclure les colonnes
d = data[:,1:-1].astype(np.int64)
#Standardisation des données * L'écart type est calculé par l'écart type non biaisé
X = (d - d.mean(axis=0)) / d.std(ddof=1,axis=0)
#Trouvez la matrice de corrélation
XX = np.round(np.dot(X.T,X) / (len(X) - 1), 2)
#Trouver la valeur propre et le vecteur de la valeur propre de la matrice de corrélation
w, V = np.linalg.eig(XX)
print('-------valeur propre-------')
print(np.round(w,3))
print('')
#Trouvez le premier composant principal
z1 = np.dot(X,V[:,0])
#Trouvez le deuxième composant principal
z2 = np.dot(X,V[:,1])
##############################################################
#Tracez un graphique du score du premier composant principal et du score du second composant principal obtenu jusqu'à présent
##############################################################
#Générer des objets pour les graphiques
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
#Insérer des lignes de quadrillage
ax.grid()
#Limite des données à dessiner
lim = [-6.0, 6.0]
ax.set_xlim(lim)
ax.set_ylim(lim)
#Amenez les axes gauche et inférieur au milieu
ax.spines['bottom'].set_position(('axes', 0.5))
ax.spines['left'].set_position(('axes', 0.5))
#Effacer les axes droit et supérieur
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
#Ajuster l'espacement des échelles des axes
ticks = np.arange(-6.0, 6.0, 2.0)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
#Ajouter une étiquette d'axe, ajuster la position
ax.set_xlabel('Z1', fontsize=16)
ax.set_ylabel('Z2', fontsize=16, rotation=0)
ax.xaxis.set_label_coords(1.02, 0.49)
ax.yaxis.set_label_coords(0.5, 1.02)
#Graphique de données
for (i,j,k) in zip(z1,z2,data[:,0]):
ax.plot(i,j,'o')
ax.annotate(k, xy=(i, j),fontsize=16)
#dessin
plt.show()
-------valeur propre-------
[ 5.589e+00 4.433e+00 2.739e+00 2.425e+00 2.194e+00 1.950e+00
1.672e+00 1.411e+00 1.227e+00 1.069e+00 9.590e-01 9.240e-01
7.490e-01 6.860e-01 5.820e-01 5.150e-01 4.330e-01 3.840e-01
2.970e-01 2.200e-01 1.620e-01 1.080e-01 8.800e-02 7.800e-02
4.600e-02 3.500e-02 -7.000e-03 -2.000e-03 4.000e-03 1.700e-02
1.300e-02]
Selon l'explication du livre, le texte avec 9 à la fin de l'étiquette est «nourriture japonaise», 2 à la fin est «ami» et 5 à la fin est «voiture».
La carte de dispersion est sortie dans la direction opposée au livre, mais les trois thèmes sont soigneusement classés: «cuisine japonaise» dans la direction supérieure gauche, «amis» dans la direction supérieure droite et «voiture» dans la direction inférieure droite. .. (Le chiffre opposé à celui du livre peut être dû à l'arbitraire d'un multiple constant de la valeur propre.)
#Coordonnées avec le vecteur propre correspondant à la plus grande valeur propre sur l'axe horizontal et le vecteur propre correspondant à la deuxième plus grande valeur propre sur l'axe vertical.
V_ = np.array([(V[:,0]),V[:,1]]).T
V_ = np.round(V_,2)
#Données pour le dessin graphique
data_name=df.columns[1:-1]
z1 = V_[:,0]
z2 = V_[:,1]
#Générer des objets pour les graphiques
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
#Insérer des lignes de quadrillage
ax.grid()
#Limite des données à dessiner
lim = [-0.4, 0.4]
ax.set_xlim(lim)
ax.set_ylim(lim)
#Amenez les axes gauche et inférieur au milieu
ax.spines['bottom'].set_position(('axes', 0.5))
ax.spines['left'].set_position(('axes', 0.5))
#Effacer les axes droit et supérieur
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
#Ajuster l'espacement des échelles des axes
ticks = np.arange(-0.4, 0.4, 0.2)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
#Ajouter une étiquette d'axe, ajuster la position
ax.set_xlabel('Z1', fontsize=16)
ax.set_ylabel('Z2', fontsize=16, rotation=0)
ax.xaxis.set_label_coords(1.02, 0.49)
ax.yaxis.set_label_coords(0.5, 1.02)
#Graphique de données
for (i,j,k) in zip(z1,z2,data_name):
ax.plot(i,j,'o')
ax.annotate(k, xy=(i, j),fontsize=14)
#dessin
plt.show()
Le coefficient de chargement est également opposé, mais le résultat est presque le même que celui du livre.
Mots susceptibles d'être liés au thème de la "cuisine japonaise" tels que "japonais" et "riz" dans la direction supérieure gauche, et mots susceptibles d'être liés au thème des "amis" tels que "meilleur ami" et "ami" dans le sens supérieur droit. Cependant, en bas à droite, il y a des mots qui semblent être liés au thème de «voiture» comme «trafic» et «accident».
Si vous le comparez avec le diagramme de dispersion des composants principaux, vous pouvez voir que les directions des mots susceptibles d'être liés à chaque thème sont les mêmes.
Lorsque j'ai détourné le code de l'article précédent, j'ai pu analyser les principaux composants des données textuelles plus facilement que prévu.
Cette fois, les données étaient déjà prétraitées proprement, donc les résultats étaient plutôt bons. La prochaine fois, je voudrais vérifier si elle peut être classée proprement dans les articles de presse.
fin
Recommended Posts