Dans Python: texte japonais: analyse morphologique J'ai appris "lire les données à analyser" et "les bases du prétraitement pour le traitement du langage naturel". Dans cet article, vous utiliserez ce que vous avez appris jusqu'à présent pour apprendre la «méthode de traitement des ensembles de données vocales» qui fait l'objet de l'analyse. En particulier, nous mettrons en œuvre un prétraitement axé sur la similitude des mots.
Le drapeau de cet ensemble de données O Parler ce n'est pas un échec On ne peut pas dire que T est un échec, mais c'est un discours étrange. X Il existe trois types d'énoncés qui semblent clairement étranges.
Ici, nous traiterons en fonction du drapeau de l'énoncé qui n'est pas un échec.
À propos des variables qui apparaissent dans l'exemple
Contenu de la variable df_label_text_O qui extrait uniquement les énoncés non brisés (ligne 49) Ndarray du tableau NumPy qui contient l'index et la colonne.
0 1
1 O Excusez-moi, qui êtes-vous?
24 O Est-ce vrai? Aimez-vous le baseball au lycée?
48 O Koshien, non?
... .. ...
2376 O Vraiment?
Contenu de la ligne variable utilisée lors du traitement de l'ensemble de données vocales non interrompues (ligne 62) row utilise tolist () Tableau NumPy ndarray df_label_text_O converti en type liste Python.
[['O', 'Excusez-moi, qui êtes-vous?'], ['O', 'Vraiment. Aimez-vous le baseball au lycée?'], ['O', 'Koshien, non?'], ... ['O', 'Est-ce vrai.']]
Cliquez ici pour un exemple
import os
import json
import pandas as pd
import re
from janome.tokenizer import Tokenizer
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste vide pour stocker les indicateurs et les énoncés
label_text = []
#Traitez 10 fichiers JSON un par un
for file in file_dir[:10]:
#Lecture en mode lecture seule
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
#Tableau de données vocales`turns`Extraire le contenu de l'énoncé et les indicateurs de
for turn in json_data['turns']:
turn_index = turn['turn-index'] #Parler tour non
speaker = turn['speaker'] #ID de l'orateur
utterance = turn['utterance'] #Contenu du discours
#Excluez la première ligne car il s'agit d'un énoncé système
if turn_index != 0:
#Extraire le contenu du discours d'une personne
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
#Extraire le drapeau d'échec
a = annotate['breakdown']
#Stockez les drapeaux et la parole humaine dans une liste
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#liste`label_text`Vers DataFrame
df_label_text = pd.DataFrame(label_text)
#Supprimer les lignes en double
df_label_text = df_label_text.drop_duplicates()
#Extraire uniquement les énoncés non réduits
df_label_text_O = df_label_text[df_label_text[0] == 'O']
t = Tokenizer()
#Créer un ensemble de données vocales non vide
morpO = [] #Stocker les mots séparés
tmp1 = []
tmp2 = ''
#Lire ligne par ligne
# .values:Lire sauf index et colonne
# .tolist:Convertir le tableau NumPy ndarray en type de liste Python
for row in df_label_text_O.values.tolist():
#Supprimer les majuscules et les minuscules des nombres et des alphabets avec des expressions régulières
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
#Effectuer une analyse morphologique avec Janome
for token in t.tokenize(reg_row):
#Le système de surface des mots`morpO`Veuillez ajouter à
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
#Sortie de mots analysés morphologiquement
pd.DataFrame(morpO)
Il a expliqué que pour analyser les données en langage naturel, les données de mots (données de phrases) devraient être converties en données numériques. Une des méthodes de conversion
Matrice de document Word (terme-Il y a quelque chose appelé matrice de document).
La matrice de document Word est une représentation tabulaire de la fréquence des mots qui apparaissent dans un document.
Les données de mots contenues dans chaque document peuvent être obtenues par analyse morphologique. À partir de là, le nombre d'occurrences de chaque mot est compté et converti en données numériques.
La matrice de document Word est un document mot / colonne dans le sens des lignes ou un document / colonne dans le sens opposé des lignes. Il est exprimé dans un format matriciel dans lequel les mots sont disposés.
Lorsqu'il y a tous les N types de mots et tous les M documents, on appelle cela une matrice de document Word de N lignes x M colonnes.
Dans la matrice de document Word de la figure, le document 1 contient le mot 1 deux fois, le mot 2 une fois, le mot 3 trois fois, ..., le mot N 0 fois. Indique qu'il apparaîtra.
Pour compter le nombre de fois où un mot apparaît
Collections de bibliothèques standard Python.Counter()Il existe plusieurs méthodes telles que l'utilisation
Ici scikit-learn (Sykit Learn) Count Vectorizer()En utilisant
Voici un exemple de création d'une matrice de document Word.
CountVectorizer()Décompose le texte en mots et compte le nombre de fois où le mot apparaît.
from sklearn.feature_extraction.text import CountVectorizer
# `CountVectorizer()`Générer un convertisseur en utilisant
CV = CountVectorizer()
corpus = ['This is a pen.',
'That is a bot.',]
# `fit_transform()`alors`corpus`Et convertissez le nombre d'occurrences de mots en un tableau
X = CV.fit_transform(corpus)
print(X)
>>>Résultat de sortie
(0, 2) 1
(0, 1) 1
(0, 4) 1
(1, 0) 1
(1, 3) 1
(1, 1) 1
# `get_feature_names()`Consultez la liste qui contient les mots que vous avez appris
print(CV.get_feature_names())
>>>Résultat de sortie
['bot', 'is', 'pen', 'that', 'this']
#Le nombre d'apparitions comptées`toarray()`Convertir en vecteur et afficher
print(X.toarray())
>>>Résultat de sortie
#ligne:`corpus`Ordre des phrases prononcées en
#Colonne:`get_feature_names()`Ordre des mots confirmé dans
[[0 1 1 0 1]
[1 1 0 1 0]]
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import CountVectorizer
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste vide pour stocker les indicateurs et les énoncés
label_text = []
#Traitez 10 fichiers JSON un par un
for file in file_dir[:10]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
#Tableau de données vocales`turns`Extraire le contenu de l'énoncé et les indicateurs de
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#liste`label_text`Vers DataFrame et supprimer les doublons
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
#Extraire uniquement les énoncés non réduits
df_label_text_O = df_label_text[df_label_text[0] == 'O']
t = Tokenizer()
#Créer un ensemble de données vocales non vide
morpO = []
tmp1 = []
tmp2 = ''
#Supprimer les majuscules et les minuscules des nombres et des alphabets
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
#Analyse morphologique avec Janome
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
#Convertir du format de liste au tableau NumPy (car le tableau est plus rapide)
morpO_array = np.array(morpO)
#Comptez le nombre de fois qu'un mot apparaît
cntvecO = CountVectorizer()
#Apprenez et convertissez les occurrences de mots en tableau
morpO_cntvecs = cntvecO.fit_transform(morpO_array)
#Convertir en tableau ndarray
morpO_cntarray = morpO_cntvecs.toarray()
#Afficher le nombre d'occurrences de mots au format DataFrame
#colonnes: mots séparés
#index (ligne): données vocales d'origine
pd.DataFrame(morpO_cntarray, columns=cntvecO.get_feature_names(),
index=morpO).head(20)
Par défaut, les mots à une seule lettre ne sont pas comptés. Il y a des mots en japonais qui ont un sens même dans une seule lettre, alors soyez prudent lorsque vous traitez avec le japonais. Pour compter même les mots d'une lettre, spécifiez token_pattern = '(? U) \ b \ w + \ b'in CountVectorizer ().
CountVectorizer(token_pattern='(?u)\\b\\w+\\b')
Dans une matrice de document Word qui a le nombre d'occurrences (fréquence) d'un mot comme valeur Les mots qui apparaissent universellement (par exemple, "I" et "desu") ont tendance à apparaître plus fréquemment dans tout document.
En revanche, les mots qui n'apparaissent que dans des documents spécifiques apparaissent moins fréquemment. Il devient difficile de caractériser chaque document à partir de mots. Par conséquent, dans la matrice de document Word
Dans TF (fréquence de terme)
Fréquence inverse des documents multipliée par IDF (fréquence inverse des documents)
TF-Les valeurs IDF sont souvent utilisées.
La valeur IDF d'un mot peut être calculée par log (nombre total de documents / nombre de documents dans lesquels un mot apparaît) + 1. Par exemple, si un mot est inclus dans 3 documents sur 4 La valeur IDF est log (4/3) + 1 ≒ 1,1 Les mots qui n'apparaissent que dans un document spécifique ont une valeur IDF plus élevée.
Une valeur IDF élevée est une caractéristique du document, car le mot est d'une grande importance.
Vous pouvez calculer l'IDF à partir du TF et calculer la valeur TF-IDF en multipliant le TF par l'IDF.
Ci-dessous est TfidfVectorizer()A été utilisé
Voici un exemple de création d'une matrice de document Word pondérée basée sur la valeur TF-IDF.
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
#Affichage après la virgule décimale avec 2 nombres valides
np.set_printoptions(precision=2)
docs = np.array([
"Blanc noir rouge", "Blanc blanc noir", "Rouge noir"
])
# `TfidfVectorizer()`Générer un convertisseur en utilisant
vectorizer = TfidfVectorizer(use_idf=True, token_pattern="(?u)\\b\\w+\\b")
# `fit_transform()`alors`docs`Et convertissez le nombre d'occurrences de mots pondérés en un tableau
vecs = vectorizer.fit_transform(docs)
print(vecs.toarray())
# >>Résultat de sortie
[[ 0.62 0.62 0.48]
[ 0.93 0. 0.36]
[ 0. 0.79 0.61]]
①vectorizer = TfidfVectorizer()alors
Génère un convertisseur qui effectue une représentation vectorielle (quantification des mots).
②use_idf=S'il est défini sur False, seul tf sera pondéré.
③vectorizer.fit_transform()Convertit le document en vecteur.
L'argument est un tableau séparé (divisé) par des espaces blancs.
④toarray()Convertit la sortie en un tableau NumPy ndarray.
np.set_printoptions()Est une fonction qui définit le format d'affichage du tableau NumPy.
print()La valeur d'origine ne change pas avec le paramètre qui n'est valide que lors de l'affichage de la valeur avec.
Précision de l'argument=Spécifiez le nombre de chiffres à afficher après la virgule décimale dans.
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste vide pour stocker les indicateurs et les énoncés
label_text = []
#Traitez 10 fichiers JSON un par un
for file in file_dir[:10]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
#Tableau de données vocales`turns`Extraire le contenu de l'énoncé et les indicateurs de
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#liste`label_text`Vers DataFrame et supprimer les doublons
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
#Extraire uniquement les énoncés non réduits
df_label_text_O = df_label_text[df_label_text[0] == 'O']
t = Tokenizer()
#Créer un ensemble de données d'énoncés qui n'est pas un repli vide
morpO = []
tmp1 = []
tmp2 = ''
#Supprimer les majuscules et les minuscules des nombres et des alphabets
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
#Analyse morphologique avec Janome
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
#Convertir du format de liste au tableau NumPy (car le tableau est plus rapide)
morpO_array = np.array(morpO)
#(1) Générer un convertisseur qui effectue une représentation vectorielle
tfidf_vecO = TfidfVectorizer(use_idf=True)
#② Convertir les mots en représentation vectorielle
morpO_tfidf_vecs = tfidf_vecO.fit_transform(morpO_array)
#③ Convertir en tableau ndarray
morpO_tfidf_array = morpO_tfidf_vecs.toarray()
#Afficher les mots (représentation vectorielle) au format DataFrame
pd.DataFrame(morpO_tfidf_array, columns=tfidf_vecO.get_feature_names(),
index=morpO).head(20)
Une quantité d'entités est une entité différente des autres données dont les données disposent.
Dans la matrice de document Word créée par CountVectorizer (), le nombre de fois qu'un mot apparaît Dans la matrice de document Word créée par TfidfVectorizer (), la valeur TF-IDF d'un mot est utilisée comme quantité de caractéristiques du mot.
Par exemple, pour distinguer si l'objet de l'image est un chien ou un chat Tout d'abord, vous remarquerez peut-être sans le savoir la forme de vos oreilles.
Dans ce cas, l'oreille (la zone y compris) est la quantité de fonction. Le problème de classification des documents utilise chaque mot comme une caractéristique pour créer un modèle d'apprentissage supervisé.
Voici à quel point les deux mots sont similaires, ce qui est différent de ce qui précède
En d'autres termes, créez un modèle d'apprentissage non supervisé avec une fonctionnalité similaire.
Une méthode familière pour mesurer la similitude est le coefficient de corrélation.
De plus, la similarité cosinus qui mesure la similitude entre les vecteurs
Le coefficient de Jaccard, qui mesure la similitude entre les ensembles, est célèbre.
Ici, la méthode corr () de pandas.DataFrame est utilisée pour trouver la similitude. Calculez le coefficient de corrélation entre chaque colonne.
La méthode corr () calcule les colonnes dont le type de données est numérique ou booléen. Les chaînes et les valeurs manquantes NaN sont exclues.
corr = DataFrame.corr()
Dans l'argument de corr (), spécifiez la méthode de calcul du coefficient de corrélation parmi les suivantes.
'pearson': Coefficient de corrélation du facteur produit de Pearson (par défaut)
'kendall': Coefficient de corrélation de rang de Kendall
'spearman': Coefficient de corrélation de rang de Spearman
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste vide pour stocker les indicateurs et les énoncés
label_text = []
#Traitez 10 fichiers JSON un par un
for file in file_dir[:10]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
#Tableau de données vocales`turns`Extraire le contenu de l'énoncé et les indicateurs de
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#liste`label_text`Vers DataFrame et supprimer les doublons
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
#Extraire uniquement les énoncés non réduits
df_label_text_O = df_label_text[df_label_text[0] == 'O']
t = Tokenizer()
#Créer un ensemble de données vocales non vide
morpO = []
tmp1 = []
tmp2 = ''
#Supprimer les majuscules et les minuscules des nombres et des alphabets
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
#Analyse morphologique avec Janome
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
# TF-Créer une matrice de document Word pondérée par valeur IDF
morpO_array = np.array(morpO)
tfidf_vecO = TfidfVectorizer(use_idf=True)
morpO_tfidf_vecs = tfidf_vecO.fit_transform(morpO_array)
morpO_tfidf_array = morpO_tfidf_vecs.toarray()
#Convertir le nombre d'occurrences de mots au format DataFrame
dtmO = pd.DataFrame(morpO_tfidf_array, columns=tfidf_vecO.get_feature_names(),
index=morpO).head(20)
#Créer une matrice de corrélation
corr_matrixO = dtmO.corr().abs()
# `.abs()`Est une méthode pour trouver la valeur absolue
#Affichage de la matrice de corrélation
corr_matrixO
A partir de là, par analyse de réseau en utilisant le coefficient de corrélation des deux mots créés dans la section précédente comme quantité de caractéristiques. Nous effectuerons une analyse quantitative.
Convertissez le coefficient de corrélation du format matriciel au format liste pour l'analyse de réseau
Pour convertir le format de matrice en format de liste
pandas.Pile DataFrame()Utilisez la méthode.
from pandas import DataFrame
#Préparer DataFrame
df=DataFrame([[0.1,0.2,0.3],[0.4,'NaN',0.5]],
columns=['test1','test2','test3'],
index=['AA','BB'])
print(df)
# >>>Résultat de sortie
test1 test2 test3
AA 0.1 0.2 0.3
BB 0.4 NaN 0.5
# stack :Conversion de colonne en ligne
print(df.stack())
# >>>Résultat de sortie
AA test1 0.1
test2 0.2
test3 0.3
BB test1 0.4
test2 NaN
test3 0.5
#unstack: conversion de ligne en colonne
print(df.unstack())
# >>>Résultat de sortie
test1 AA 0.1
BB 0.4
test2 AA 0.2
BB NaN
test3 AA 0.3
BB 0.5
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste d'indicateurs et d'énoncés
label_text = []
for file in file_dir[:10]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#Supprimer les doublons et extraire uniquement les énoncés non cassés
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
df_label_text_O = df_label_text[df_label_text[0] == 'O']
#Analyse morphologique par Janome
t = Tokenizer()
morpO = []
tmp1 = []
tmp2 = ''
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
# TF-Créer une matrice de document Word pondérée par valeur IDF
morpO_array = np.array(morpO)
tfidf_vecO = TfidfVectorizer(use_idf=True)
morpO_tfidf_vecs = tfidf_vecO.fit_transform(morpO_array)
morpO_tfidf_array = morpO_tfidf_vecs.toarray()
#Convertir au format DataFrame et créer une matrice de corrélation
dtmO = pd.DataFrame(morpO_tfidf_array, columns=tfidf_vecO.get_feature_names(),
index=morpO)
corr_matrixO = dtmO.corr().abs()
#Matrice de corrélation`corr_matrixO`Conversion de la direction de la colonne à la direction de la ligne
corr_stackO = corr_matrixO.stack()
index = pd.Series(corr_stackO.index.values)
value = pd.Series(corr_stackO.values)
#Le coefficient de corrélation est 0.5 ou plus 1.Extraire moins de 0
tmp3 = [] #Le coefficient de corrélation est 0.5 ou plus 1.Liste des valeurs d'index avec des valeurs inférieures à 0
tmp4 = [] #Le coefficient de corrélation est 0.5 ou plus 1.Liste des valeurs de valeur inférieures à 0
for i in range(0, len(index)):
if value[i] >= 0.5 and value[i] < 1.0:
tmp1 = str(index[i][0]) + ' ' + str(index[i][1])
tmp2 = [s for s in tmp1.split()]
tmp3.append(tmp2)
tmp4 = np.append(tmp4, value[i])
tmp3 = pd.DataFrame(tmp3)
tmp3 = tmp3.rename(columns={0: 'node1', 1: 'node2'})
tmp4 = pd.DataFrame(tmp4)
tmp4 = tmp4.rename(columns={0: 'weight'})
# DataFrame`tmp3`Quand`tmp4`Veuillez vous connecter dans le sens horizontal
df_corlistO = pd.concat([tmp3, tmp4], axis=1)
#Afficher le DataFrame créé
df_corlistO.head(20)
La mise en réseau est une manière d'exprimer la relation entre les objets. Un exemple bien connu est le réseau d'amitiés sur SNS.
Dans la structure du réseau
La cible est un nœud
Les relations sont représentées par des arêtes.
Les bords ont du poids et sont intimes dans les réseaux d'amitié. Plus vous êtes proche, plus la valeur de poids est élevée.
En outre, les cartes routières, les réseaux aéronautiques et les relations de cooccurrence / similaires de mots peuvent être exprimés dans des réseaux.
Pour visualiser un groupe de langages qui n'ont pas de concept de direction sur les bords et qui ne sont pas liés, comme la liste de similarité créée dans la section précédente.
Utilisez un graphe non dirigé (ou un réseau non dirigé).
Le graphe pondéré est également appelé réseau.
Un graphe non orienté est un graphe dans lequel les arêtes qui composent le réseau n'ont pas de direction. Au contraire, si l'arête est directionnelle
C'est ce qu'on appelle un graphe orienté (ou réseau orienté).
Python a une bibliothèque appelée NetworkX. Cette section utilise cette bibliothèque pour visualiser la liste de similarité créée dans la section précédente.
#Bibliothèque`NetworkX`Importer
import networkx as nx
#Créer un graphique non orienté
network = nx.from_pandas_edgelist(df, source='source', target='target', edge_attr=None, create_using=None)
① df: nom DataFrame de Pandas qui est la source du graphique
② source: nom de colonne du nœud source
Spécifiez avec str (type chaîne de caractères) ou int (type entier)
③ target: nom de colonne du nœud cible
Spécifiez avec str ou int
④edge_attr: Bord (poids) de chaque donnée
Spécifiez avec str ou int, iterable, True
⑤create_en utilisant: Type de graphique (facultatif)
Graphique non dirigé: nx.Graphique (par défaut)
Graphique dirigé: nx.DiGraph
#Bibliothèque`Matplotlib`De`pyplot`Importer
from matplotlib import pyplot
#Calculez la position d'affichage optimale pour chaque nœud
pos = nx.spring_layout(graph)
#Dessinez un graphique
nx.draw_networkx(graph, pos)
#Afficher des graphiques à l'aide de Matplotlib
plt.show()
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
import networkx as nx
import matplotlib.pyplot as plt
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste d'indicateurs et d'énoncés
label_text = []
for file in file_dir[:10]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#Supprimer les doublons et extraire uniquement les énoncés non cassés
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
df_label_text_O = df_label_text[df_label_text[0] == 'O']
#Analyse morphologique par Janome
t = Tokenizer()
morpO = []
tmp1 = []
tmp2 = ''
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
# TF-Créer une matrice de document Word pondérée par valeur IDF
morpO_array = np.array(morpO)
tfidf_vecO = TfidfVectorizer(use_idf=True)
morpO_tfidf_vecs = tfidf_vecO.fit_transform(morpO_array)
morpO_tfidf_array = morpO_tfidf_vecs.toarray()
#Convertir au format DataFrame et créer une matrice de corrélation
dtmO = pd.DataFrame(morpO_tfidf_array)
corr_matrixO = dtmO.corr().abs()
#Création d'un ensemble de données vocales non interrompu
corr_stackO = corr_matrixO.stack()
index = pd.Series(corr_stackO.index.values)
value = pd.Series(corr_stackO.values)
tmp3 = []
tmp4 = []
for i in range(0, len(index)):
if value[i] >= 0.5 and value[i] < 1.0:
tmp1 = str(index[i][0]) + ' ' + str(index[i][1])
tmp2 = [int(s) for s in tmp1.split()]
tmp3.append(tmp2)
tmp4 = np.append(tmp4, value[i])
tmp3 = pd.DataFrame(tmp3)
tmp3 = tmp3.rename(columns={0: 'node1', 1: 'node2'})
tmp4 = pd.DataFrame(tmp4)
tmp4 = tmp4.rename(columns={0: 'weight'})
df_corlistO = pd.concat([tmp3, tmp4], axis=1)
#① Créez un graphe non orienté
G_corlistO = nx.from_pandas_edgelist(df_corlistO, 'node1', 'node2', ['weight'])
#② Visualisez le graphique créé
#Paramètres de mise en page
pos = nx.spring_layout(G_corlistO)
nx.draw_networkx(G_corlistO, pos)
plt.show()
Comme le montre le graphique visualisé dans la section précédente, le réseau réel a de nombreuses structures compliquées. À première vue, il est difficile de saisir les caractéristiques.
Dans un tel cas, saisissez les caractéristiques quantitativement avec un certain indice. Certains des indicateurs servent à comprendre l'ensemble du réseau (mondial). Il y a aussi des choses (locales) qui se concentrent sur un certain nœud et le saisissent.
Voici quelques exemples d'indicateurs couramment utilisés:
Ordre: indique le nombre d'arêtes du nœud.
Distribution de l'ordre: représente un histogramme du nombre de nœuds avec un certain ordre.
Coefficient de cluster: indique à quel point les nœuds sont connectés.
Longueur de l'itinéraire: distance d'un nœud à un autre.
Centralité: représente le degré auquel un nœud joue un rôle central dans le réseau.
Maintenant, pour le réseau créé dans la section précédente, calculez le coefficient de cluster et la centralité de la médiation. Regardons les fonctionnalités.
Dans ce réseau Le coefficient de cluster est la densité de connexion entre les mots La centralité de la médiation représente le degré de plaque tournante d'un mot dans un réseau.
Comparaison du coefficient de cluster moyen pour chaque réseau, parole non défaillante et parole interrompue Vous pouvez voir que les mots du discours qui sont brisés sont plus étroitement liés.
Aussi, si vous comparez les 5 premiers mots avec une centralité de médiation élevée Les mots concernant les vacances d'Obon sont inclus dans les énoncés non condensés On peut en déduire que les mots de baseball tôt le matin jouent un rôle central dans le discours effondré.
① Parler ce n'est pas un échec
<Coefficient de cluster moyen> 0.051924357
<Top 5 des mots à forte centralité de médiation>
Vacances, Obon, ici, peu, aube
② Une histoire qui est cassée
<Coefficient de cluster moyen> 0.069563257
<Top 5 des mots à forte centralité de médiation>
Cette fois, jouons au baseball, tôt le matin, il
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
import networkx as nx
import matplotlib.pyplot as plt
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste d'indicateurs et d'énoncés
label_text = []
for file in file_dir[:10]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#Supprimer les doublons et extraire uniquement les énoncés non cassés
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
df_label_text_O = df_label_text[df_label_text[0] == 'O']
#Analyse morphologique par Janome
t = Tokenizer()
morpO = []
tmp1 = []
tmp2 = ''
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
# TF-Créer une matrice de document Word pondérée par valeur IDF
morpO_array = np.array(morpO)
tfidf_vecO = TfidfVectorizer(use_idf=True)
morpO_tfidf_vecs = tfidf_vecO.fit_transform(morpO_array)
morpO_tfidf_array = morpO_tfidf_vecs.toarray()
#Convertir au format DataFrame et créer une matrice de corrélation
dtmO = pd.DataFrame(morpO_tfidf_array, columns=tfidf_vecO.get_feature_names(),
index=morpO)
corr_matrixO = dtmO.corr().abs()
#Création d'un ensemble de données vocales non interrompu
corr_stackO = corr_matrixO.stack()
index = pd.Series(corr_stackO.index.values)
value = pd.Series(corr_stackO.values)
tmp3 = []
tmp4 = []
for i in range(0, len(index)):
if value[i] >= 0.5 and value[i] < 1.0:
tmp1 = str(index[i][0]) + ' ' + str(index[i][1])
tmp2 = [s for s in tmp1.split()]
tmp3.append(tmp2)
tmp4 = np.append(tmp4, value[i])
tmp3 = pd.DataFrame(tmp3)
tmp3 = tmp3.rename(columns={0: 'node1', 1: 'node2'})
tmp4 = pd.DataFrame(tmp4)
tmp4 = tmp4.rename(columns={0: 'weight'})
df_corlistO = pd.concat([tmp3, tmp4], axis=1)
#Créer un graphique non dirigé
G_corlistO = nx.from_pandas_edgelist(df_corlistO, 'node1', 'node2', ['weight'])
#Pour les ensembles de données vocales non interrompues
#① Calcul du coefficient de cluster moyen
print('Coefficient de cluster moyen')
print(nx.average_clustering(G_corlistO, weight='weight'))
print()
#② Calcul de la centralité de la médiation
bc = nx.betweenness_centrality(G_corlistO, weight='weight')
print('Centralité de la médiation')
for k, v in sorted(bc.items(), key=lambda x: -x[1]):
print(str(k) + ': ' + str(v))
Plus le coefficient de cluster moyen de tous les nœuds est élevé, plus le réseau est dense. La moyenne des coefficients de cluster est calculée à l'aide de nx.average_clustering ().
nx.average_clustering(G, weight=None)
①G
Spécifiez le graphique.
(Graphe non dirigé G créé dans la section précédente_corlistO)
②weight
Spécifie l'arête avec le nombre à utiliser comme poids. Si aucun, le poids de chaque arête sera de 1.
Il est déterminé par le nombre de nœuds inclus dans l'itinéraire le plus court entre tous les nœuds. En d'autres termes, les nœuds les plus utilisés pour transmettre efficacement des informations sont plus intermédiaires et centraux.
nx.betweenness_centrality(G, weight=None)
①G
Spécifiez le graphique.
(Graphe non dirigé G créé dans la section précédente_corlistO)
②weight
Spécifie l'arête avec le nombre à utiliser comme poids. Si aucun, tous les poids de bord sont considérés comme égaux.
Un réseau est composé de plusieurs réseaux partiels (= communautés). Chaque nœud de la communauté est caractérisé par le fait qu'il est étroitement connecté à la périphérie.
Si vous supprimez les bords clairsemés d'un réseau, vous pouvez le diviser en réseaux partiels. En d'autres termes, la communauté peut être extraite = les réseaux à forte similitude peuvent être extraits.
Pour diviser le réseau
Nous utilisons un index appelé Modularité.
Modularité De "Rapport du nombre d'arêtes dans la communauté au nombre total d'arêtes dans un réseau" "Pour l'ordre total de tous les nœuds dans un réseau (égal au nombre d'arêtes dans le réseau x 2) Quantifiez la qualité de la scission en soustrayant le «pourcentage total de l'ordre des nœuds dans la communauté».
Plus la valeur de modularité est élevée, plus les nœuds de la communauté sont serrés.
Extrayons maintenant la communauté en utilisant la modularité. Énoncés intacts et énoncés brisés dans leurs réseaux respectifs Quand j'ai vérifié les mots de la communauté avec le plus grand nombre de nœuds, j'ai obtenu les résultats suivants.
① Parler ce n'est pas un échec
Obon, fin, juste, repos, coupe, problème, peu, retour à la maison, oubliant, paresseux, aube, continuer, vacances consécutives, concentration
② Une histoire qui est cassée
S'il vous plaît, à propos de, à propos de, puis prenez, qui, dépendance, bien sûr, bien, travail, biais, division, danger, attendez, esprit, temps, nutrition, insouciance, sommeil, repas
Pour les énoncés non réduits, par exemple, "J'ai beaucoup de vacances à Obon et j'ai du mal à rentrer chez moi" Vous pouvez deviner qu'il y a un sujet.
Les énoncés qui sont brisés comprennent, par exemple, «essayez de ne pas biaiser la nutrition de l'alimentation» et «dormez suffisamment». Il semble y avoir un sujet.
De même, vous devriez être capable de deviner à partir des mots quels sujets sont inclus dans d'autres communautés.
greedy_modularity_communities(G, weight=None)
①G
Spécifiez le graphique.
(Graphe non dirigé G créé dans la section précédente_corlistO)
②weight
Spécifie l'arête avec le nombre à utiliser comme poids. Si aucun, tous les poids de bord sont considérés comme égaux.
Cliquez ici pour des exemples d'utilisation
import os
import json
import pandas as pd
import numpy as np
import re
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer
import networkx as nx
import matplotlib.pyplot as plt
from networkx.algorithms.community import greedy_modularity_communities
#spécifier le répertoire init100
file_path = './6110_nlp_preprocessing_data/init100/'
file_dir = os.listdir(file_path)
#Créez une liste d'indicateurs et d'énoncés
label_text = []
for file in file_dir[:20]:
r = open(file_path + file, 'r', encoding='utf-8')
json_data = json.load(r)
for turn in json_data['turns']:
turn_index = turn['turn-index']
speaker = turn['speaker']
utterance = turn['utterance']
if turn_index != 0:
if speaker == 'U':
u_text = ''
u_text = utterance
else:
a = ''
for annotate in turn['annotations']:
a = annotate['breakdown']
tmp1 = str(a) + '\t' + u_text
tmp2 = tmp1.split('\t')
label_text.append(tmp2)
#Supprimer les doublons et extraire uniquement les énoncés non cassés
df_label_text = pd.DataFrame(label_text)
df_label_text = df_label_text.drop_duplicates()
df_label_text_O = df_label_text[df_label_text[0] == 'O']
#Analyse morphologique par Janome
t = Tokenizer()
morpO = []
tmp1 = []
tmp2 = ''
for row in df_label_text_O.values.tolist():
reg_row = re.sub('[0-9a-zA-Z]+', '', row[1])
reg_row = reg_row.replace('\n', '')
for token in t.tokenize(reg_row):
tmp1.append(token.surface)
tmp2 = ' '.join(tmp1)
morpO.append(tmp2)
tmp1 = []
# TF-Créer une matrice de document Word pondérée par valeur IDF
morpO_array = np.array(morpO)
tfidf_vecO = TfidfVectorizer(use_idf=True)
morpO_tfidf_vecs = tfidf_vecO.fit_transform(morpO_array)
morpO_tfidf_array = morpO_tfidf_vecs.toarray()
#Convertir au format DataFrame et créer une matrice de corrélation
dtmO = pd.DataFrame(morpO_tfidf_array, columns=tfidf_vecO.get_feature_names(),
index=morpO)
corr_matrixO = dtmO.corr().abs()
#Création d'un ensemble de données vocales non interrompu
corr_stackO = corr_matrixO.stack()
index = pd.Series(corr_stackO.index.values)
value = pd.Series(corr_stackO.values)
tmp3 = []
tmp4 = []
for i in range(0, len(index)):
if value[i] >= 0.5 and value[i] < 1.0:
tmp1 = str(index[i][0]) + ' ' + str(index[i][1])
tmp2 = [s for s in tmp1.split()]
tmp3.append(tmp2)
tmp4 = np.append(tmp4, value[i])
tmp3 = pd.DataFrame(tmp3)
tmp3 = tmp3.rename(columns={0: 'node1', 1: 'node2'})
tmp4 = pd.DataFrame(tmp4)
tmp4 = tmp4.rename(columns={0: 'weight'})
df_corlistO = pd.concat([tmp3, tmp4], axis=1)
#Créer un graphique non dirigé
G_corlistO = nx.from_pandas_edgelist(df_corlistO, 'node1', 'node2', ['weight'])
#Pour les ensembles de données vocales non interrompues
#Extraction communautaire
cm_corlistO = list(greedy_modularity_communities(G_corlistO, weight='weight'))
#Afficher les nœuds appartenant à chaque communauté
cm_corlistO
Recommended Posts