[PYTHON] Traiter le nom de la carte Yugioh en langage naturel --Yugiou Data Science 2. PNL

introduction

Il s'agit de la série "Yugio DS (Data Science)" qui analyse diverses données de cartes Yugioh en utilisant Python. L'article aura lieu quatre fois au total, et enfin nous mettrons en œuvre un programme qui prédit les attributs offensifs et défensifs des noms de cartes par traitement du langage naturel + apprentissage automatique. De plus, la connaissance de Yugioh par l'auteur s'est arrêtée aux alentours de E ・ HERO. Je suis désolé que les cartes et la science des données soient des amateurs, mais veuillez rester en contact.

No. Le titre de l'article Keyword
0 Obtenir des informations sur la carte de la base de données Yugioh-Yugioh DS 0.Grattage beautifulsoup
1 Visualisez les données de la carte Yugioh avec Python-Yugioh Data Science 1.Édition EDA pandas, seaborn
2 Traitez le nom de la carte Yugioh en langage naturel-Yugioh DS 2.Édition PNL wordcloud, word2vec, doc2vec, t-SNE Cet article!
3 Prédire les attributs offensifs et défensifs à partir du nom de la carte Yugioh-Yugioh DS 3.Apprentissage automatique lightgbm etc.

Objectif de cet article

1. EDA approfondira le "nom de la carte" qui n'était pas ciblé. Divers monstres tels que des dragons, des sorciers et des HÉROS apparaîtront dans Yugioh, mais nous explorerons les types de mots souvent utilisés dans le nom. En outre, je voudrais voir quelles similitudes chacun a lorsqu'il est séparé par attribut / type / niveau. Les thèmes techniques de cet article sont l'analyse morphologique avec «MeCab», la visualisation fréquente de mots avec «WordCloud», la représentation distribuée des mots avec «Word2Vec» et «Doc2Vec», la compression de dimension et le mappage de mots avec «t-SNE». Je vais vous expliquer étape par étape avec le code d'implémentation.

Explication des prérequis (environnement d'utilisation, données, politique d'analyse)

environnement d'utilisation

Python==3.7.4

Les données

Les données acquises dans cet article sont récupérées avec un code fait à la main de Yugio OCG Card Database. .. Il s'agit du dernier en juin 2020. Différents blocs de données sont utilisés selon le graphique à afficher, mais tous les blocs de données contiennent les colonnes suivantes.

No. Nom de colonne Nom de colonne(日本語) échantillon Supplément
1 name nom de la carte Jaune Ojama
2 kana Lire le nom de la carte Jaune Ojama
1 rarity Rareté Ordinaire Pour faciliter l'acquisition, des informations telles que «restriction» et «interdiction» sont également incluses.
1 attr attribut 光attribut Pour les non-monstres, entrez "magie" et "piège"
1 effect effet NaN Contient les types de cartes magie / piège tels que «permanent» et «équipement». NaN pour les monstres
1 level niveau 2 Entrez "Rang 2" pour les monstres de rang
1 species Course Tribu de la bête
1 attack Puissance offensive 0
1 defence Puissance défensive 1000
1 text Texte de la carte Un membre du trio jama dont on dit qu'il joue par tous les moyens. Quand quelque chose se passe quand nous sommes tous les trois ensemble...
1 pack Nom du pack d'enregistrement EXPERT Expert EDITION Edition Volume Volume 2
1 kind type - Dans le cas d'une carte monstre, des informations telles que la fusion et le rituel sont saisies

image.png

Politique d'analyse

Toutes les analyses sont destinées à être effectuées dans un interpréteur interactif tel que «Jupter Lab».

la mise en oeuvre

1. Importation de package

Importez les packages requis. Je ne pense pas que MeCab, gensim et wordcloud soient inclus dans Anaconda depuis le début, donc je ferai pip install si nécessaire.

python


import matplotlib.pyplot as plt
import MeCab
import numpy as np
import pandas as pd
import re
import seaborn as sns
from gensim.models.doc2vec import Doc2Vec
from gensim.models.doc2vec import TaggedDocument
from gensim.models import word2vec
from sklearn.decomposition import TruncatedSVD
from sklearn.manifold import TSNE
from PIL import Image
from wordcloud import WordCloud
%matplotlib inline
sns.set(font="IPAexGothic") #Prend en charge Python en japonais

2. Importation de données

La méthode d'acquisition de chaque jeu de données est décrite dans 0. Scraping (pas d'article en juin 2020).

python


#Non utilisé cette fois
# all_data = pd.read_csv("./input/all_data.csv") #Ensemble de données pour toutes les cartes (les cartes portant le même nom ont des packs d'enregistrement en double)
# print("all_data: {}rows".format(all_data.shape[0]))

cardlist = pd.read_csv("./input/cardlist.csv") #Jeu de données pour toutes les cartes (pas de duplication)
print("cardlist: {}rows".format(cardlist.shape[0]))

#Non utilisé cette fois
# monsters = pd.read_csv("./input/monsters.csv") #Carte Monstre uniquement
# print("monsters: {}rows".format(monsters.shape[0]))

monsters_norank = pd.read_csv("./input/monsters_norank.csv") #Retirer les monstres de rang des cartes monstre
print("monsters_norank: {}rows".format(monsters_norank.shape[0]))
cardlist: 10410rows
monsters_norank: 6206rows

3. Vérification MeCab

La procédure d'utilisation de MeCab est à peu près les 2 étapes suivantes.

  1. Instancier un analyseur morphologique sous la forme de «mecab Tagger»
  2. Exécutez la méthode parseToNode () qui effectue une analyse morphologique et stockez le résultat dans l'objet node.

En raison de ce qui précède, l'objet node contient deux attributs.

python


# 1.Instanciez un analyseur morphologique et stockez le résultat du traitement dans un objet avec la méthode parseToNode
text = "Dragon blanc aux yeux bleus"
mecabTagger = MeCab.Tagger("-Ochasen -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/") #Dictionnaire: mecab-ipadic-Utilisez neologd
node = mecabTagger.parseToNode(text)

#2.Type de surface(surface)Et identité(feature)Créer un bloc de données à stocker
surface_and_feature = pd.DataFrame()
surface = []
feature = []

#3.Extraire la forme de la surface et l'identité des attributs de l'objet nœud
while node:
    surface.append(node.surface)
    feature.append(node.feature)
    node = node.next
    
surface_and_feature['surface'] = surface
surface_and_feature['feature'] = feature

surface_and_feature

image.png

Il semble que feature contienne une liste, nous allons donc la convertir en bloc de données. Lors de l'utilisation du dictionnaire mecab-ipadic-neologd, le contenu de la fonction est ** partie paroles (pos), partie paroles sous-classification 1 (pos1), partie partie sous-classification 2 (pos2), partie partie sous-classification 3 (pos3) ), Le type d'utilisation (ctype), le type d'utilisation (cform), le prototype (base), la lecture (lecture), la prononciation (prononcer) ** sont stockés sous forme de liste. De plus, «BOS / EOS» au début et à la fin de la trame de données est une valeur qui représente directement le début et la fin du «nœud».

python


text = "Dragon blanc aux yeux bleus"
mecabTagger = MeCab.Tagger("-Ochasen -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/")
node = mecabTagger.parseToNode(text)

#Identité(feature)Contenu de la liste(Partie,Partie細分類1,Partie細分類2,Partie細分類3,Type d'utilisation,Type d'utilisation,Prototype,en train de lire,prononciation)Dans une trame de données
features = pd.DataFrame(columns=["pos","pos1","pos2","pos3","ctype","cform","base","read","pronounce"])
posses = pd.DataFrame
while node:
    tmp = pd.Series(node.feature.split(','), index=features.columns)
    features = features.append(tmp, ignore_index=True)
    node = node.next
    
features

image.png

4. Analyse morphologique

Les données lues sont appliquées à l'analyseur morphologique MeCab.

4-1. Mise en œuvre d'une fonction qui effectue une analyse morphologique

Créez une fonction get_word_list qui décompose une liste de noms de cartes en mots. Si vous ajoutez des mots auxiliaires tels que "to" et "mo", ce sera bruyant, donc n'utilisez que ** nomenclature, verbes et adjectifs **.

python


def get_word_list(text_list):
    m = MeCab.Tagger ("-Ochasen -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/")
    lines = []
    for text in text_list:
        keitaiso = []
        m.parse('')
        node = m.parseToNode(text)
        while node:
            #Mettre la morphologie dans le dictionnaire
            tmp = {}
            tmp['surface'] = node.surface
            tmp['base'] = node.feature.split(',')[-3] #Prototype(base)
            tmp['pos'] = node.feature.split(',')[0] #Partie(pos)
            tmp['pos1'] = node.feature.split(',')[1] #Reclassement de mot partiel(pos1)
            
            #BOS représentant le début et la fin d'une phrase/Omettre EOS
            if 'BOS/EOS' not in tmp['pos']:
                keitaiso.append(tmp)
                
            node = node.next
        lines.append(keitaiso)
    
    #Stockez le système de surface pour la nomenclature et la forme originale pour les verbes / adjectifs dans la liste.
    word_list = [] 
    for line in lines:
        for keitaiso in line:
            if (keitaiso['pos'] == 'nom'):
                word_list.append(keitaiso['surface'])
            elif  (keitaiso['pos'] == 'verbe') | (keitaiso['pos'] == 'adjectif') :
                if not keitaiso['base'] == '*' :
                    word_list.append(keitaiso['base'])
                else: 
                    word_list.append(keitaiso['surface'])
#Décommenter si vous incluez la nomenclature, les verbes et les adjectifs
#             else:
#                 word_list.append(keitaiso['surface'])

    return word_list

4-2. Création d'un bloc de données

Créez deux cadres de données à utiliser dans les processus de visualisation et de modélisation ultérieurs.

Au fait, dans le nom de la carte Yugioh, il y a de nombreuses divisions de mots par le symbole «・», mais «Mecab» ne divise pas ce symbole. Par conséquent, avant d'exécuter la fonction ci-dessus, insérez à l'avance le processus de division du mot par "・".

cardlist_word_count

python


#"・" Crée une liste de noms pré-séparée
namelist = []
for name in cardlist.name.to_list():
    for name_ in name.split("・"):
        namelist.append(name_)
    
#Fonction get_word_Liste de chaînes de caractères mot par liste_Générer une liste
word_list = get_word_list(namelist)

# word_Mots de bloc de données qui mappent les mots et leur fréquence d'occurrence à partir de la liste_Génération de df
word_freq = pd.Series(word_list).value_counts()
cardlist_word_count = pd.DataFrame({'word' : word_freq.index,
             'word_count' : word_freq.tolist()})

cardlist_word_count

image.png

monsters_words

python


monsters_words= pd.DataFrame(columns=["word","name","level","attr","rarity","species","kind"])
for i, name in enumerate(monsters_norank.name.to_list()):
    words = get_word_list(name.split("・"))
    names = [monsters_norank.loc[i, "name"] for j in words]
    levels = [monsters_norank.loc[i, "level"] for j in words]
    attrs = [monsters_norank.loc[i, "attr"] for j in words]
    rarities = [monsters_norank.loc[i, "rarity"] for j in words]
    species = [monsters_norank.loc[i, "species"] for j in words]
    kinds = [monsters_norank.loc[i, "kind"] for j in words]
    tmp = pd.DataFrame({"word" : words, "name" : names, "level" : levels, "attr" : attrs, "rarity" : rarities, "species" : species, "kind" : kinds})
    monsters_words = pd.concat([monsters_words, tmp])
    
monsters_words

image.png

5. Visualisation

5-1. Classement des mots utilisé

À partir de cardlist_word_count, retirez 50 mots fréquents de toutes les cartes et faites un classement. "Dragon" est extrêmement numéro un avec 326 fois. Un total de 610 fois est apparu avec des mots similaires «dragon (3e place)» et «dragon (98e place)».

nlp5-1.png

python


df4visual = cardlist_word_count.head(50)

f, ax = plt.subplots(figsize=(20, 10))
ax = sns.barplot(data=df4visual, x="word", y="word_count")
ax.set_ylabel("frequency")
ax.set_title("Classement des mots utilisé dans toutes les cartes")

for i, patch in enumerate(ax.patches):
    ax.text(i, patch.get_height()/2, int(patch.get_height()), ha='center')

plt.xticks(rotation=90)
plt.savefig('./output/nlp5-1.png', bbox_inches='tight', pad_inches=0)

Du coup, j'étais curieux de savoir comment utiliser correctement «dragon» et «dragon» dans le classement, je vais donc faire un détour et procéder à la recherche. Prenez un niveau sur l'axe des abscisses et dessinez les résultats de l'estimation de la densité du noyau pour chacun des mots «dragon» et «dragon». Chaque montagne est dessinée de manière à ce que la superficie totale soit de 1, et on peut interpréter que de nombreux monstres sont rassemblés dans la partie haute de la montagne. Le dragon a un sommet de montagne sur le côté droit du graphique par rapport au dragon, vous pouvez donc voir qu'il est utilisé pour des cartes de niveau relativement élevé et fortes.

nlp5-1a.png

python


monsters_words_dragon = monsters_words.query("word == 'dragon' | word == 'Dragon'")
df4visual = monsters_words_dragon

f, ax = plt.subplots(figsize = (20, 5))
ax = sns.kdeplot(df4visual.query("word == 'dragon'").level, label="dragon")
ax = sns.kdeplot(df4visual.query("word == 'Dragon'").level, label="Dragon")
ax.set_xlim([0, 12]);
ax.set_title("Dragon/Distribution du noyau Dragon")
ax.set_xlabel("level")
plt.savefig('./output/nlp5-1a.png', bbox_inches='tight', pad_inches=0)

Le code source et l'interprétation sont omis, mais les résultats du count plot par niveau et attribut sont également affichés.

nlp5-1b.png nlp5-1c.png

5-2. WordCloud

Word Cloud est une bibliothèque utilisée pour la visualisation de mots. Extrayez les mots les plus fréquents et dessinez les mots les plus fréquents dans une taille plus grande. wordcloud.generate_from_frequencies () prend un dictionnaire de mots et leur fréquence pour générer un objet WordCloud. Si vous regardez la figure, vous pouvez voir que le "dragon" est tracé dans la plus grande taille, comme dans 5-1.

nlp5-2a.png

python


def make_wordcloud(df,col_name_noun,col_name_quant):
    word_freq_dict = {}
    for i, v in df.iterrows(): #Dictionnaire des mots et leur fréquence à partir des trames de données
        word_freq_dict[v[col_name_noun]] = v[col_name_quant]
    fpath = "/System/Library/Fonts/Hiragino Kaku Gothic W3.ttc"
    
    #Instancier WordCloud
    wordcloud = WordCloud(background_color='white',
                        font_path = fpath,
                          min_font_size=10,
                         max_font_size=200,
                         width=2000,
                         height=500
                         )
    wordcloud.generate_from_frequencies(word_freq_dict)
    return wordcloud

f, ax = plt.subplots(figsize=(20, 5))
ax.imshow(make_wordcloud(cardlist_word_count, 'word', 'word_count'))
ax.axis("off")
ax.set_title("Toutes les cartes WordCloud")
plt.savefig('./output/nlp5-2a.png', bbox_inches='tight', pad_inches=0)

Les résultats d'extraction par niveau et attribut sont également affichés. Ce sera un peu vertical, mais si vous n'êtes pas intéressé, faites défiler et sautez-le.

** Par niveau ** Il y a des "dragons" uniformément aux niveaux 1-12, mais au niveau 9 il y a plus de "dragons", et au niveau 11, il ne semble pas y avoir de dragon lui-même en premier lieu. nlp5-2b.png

** Par attribut ** Les mots de type guerrier tels que guerrier et épargnant se démarquent dans l'attribut terre. Il va sans dire qu'il existe de nombreux attributs sombres tels que «diable», «sombre» et «démon». nlp5-2c.png

python


def make_wordclouds(df, colname):
    wordclouds = []
    df = df.sort_values(colname)
    for i in df[colname].unique():
        # word_freq = df.query("{} == {}".format(colname,i))["word"].value_counts() #Convertir en série et valeur pandas_counts()
        word_freq = df[df[colname] == i]["word"].value_counts()
        monsters_word_count = pd.DataFrame({'word' : word_freq.index, 'word_count' : word_freq.tolist()})
        wordclouds.append(make_wordcloud(monsters_word_count, 'word', 'word_count'))

    f, ax = plt.subplots(len(wordclouds), 1, figsize=(20, 5*int(len(wordclouds))))
    for i, wordcloud in enumerate(wordclouds):
        ax[i].imshow(wordcloud)
        ax[i].set_title("{}:".format(colname) + str(df[colname].unique()[i]))
        ax[i].axis("off");
        
make_wordclouds(monsters_words, "level")
plt.savefig('./output/nlp5-2b.png', bbox_inches='tight', pad_inches=0)

make_wordclouds(monsters_words, "attr")
plt.savefig('./output/nlp5-2c.png', bbox_inches='tight', pad_inches=0)

6. Modélisation (expression distribuée de mots / phrases)

La vectorisation est faite pour permettre aux machines d'interpréter plus facilement la signification des mots afin d'améliorer la similitude entre les mots et de procéder au processus d'apprentissage automatique ultérieur. La conversion d'un mot en un vecteur de plusieurs dimensions à plusieurs centaines de dimensions s'appelle ** représentation distribuée **. Cette fois, nous utiliserons word2vec pour l'expression distribuée des mots. En passant une liste de mots, vous pouvez facilement la convertir en vecteur avec n'importe quel nombre de dimensions. De plus, «Doc2Vec» est utilisé pour la vectorisation des unités de phrase.

Veuillez vous référer aux liens suivants pour le mécanisme détaillé et l'utilisation de Word2Vec et Doc2Vec.

6-1. Word2Vec

Comme préparation préliminaire, modifiez davantage le bloc de données monsters_words créé dans le chapitre précédent pour créer monsters_wordlist. Renvoyez l'unité de ligne à l'unité monstre, et ajoutez une nouvelle liste de mots inclus dans cette carte dans la colonne «liste de mots» et le nombre de mots comme colonne «longueur».

python


wordlist = monsters_words.groupby("name")["word"].apply(list).reset_index()
wordlist.columns = ["name", "wordlist"]
wordlist["length"] = wordlist["wordlist"].apply(len)

monsters_wordlist = pd.merge(wordlist, monsters_norank, how="left")
monsters_wordlist

image.png

Voici le code qui effectue réellement la modélisation. size est le nombre de dimensions, ʻiter est le nombre de répétitions d'apprentissage, et windwow` est un paramètre qui indique le nombre de mots avant et après à apprendre.

python


%time model_w2v = word2vec.Word2Vec(monsters_wordlist["wordlist"], size=30, iter=3000, window=3)
model_w2v

Après avoir appris, vérifions-le facilement. La méthode wv.most_similar () vous permet de voir les n premiers mots qui sont déterminés pour avoir des significations similaires à un mot. Quand j'ai essayé de saisir "rouge", "** noir **", qui représente également la couleur, est venu en premier. C'est un sentiment agréable! Si ce résultat de recommandation n'est pas correct, déplacez les paramètres ci-dessus de différentes manières et répétez la vérification.

python


model_w2v.wv.most_similar(positive="rouge", topn=20)
[('noir', 0.58682781457901),
 ('Diable', 0.5581836700439453),
 ('Artefact', 0.5535239577293396),
 ('fantôme', 0.4850098788738251),
 ('Être', 0.460792601108551),
 ('de', 0.4455495774745941),
 ('Ancien', 0.43780404329299927),
 ('L'eau', 0.4303821623325348),
 ('Dragon', 0.4163920283317566),
 ('Saint', 0.4114375710487366),
 ('Genèse', 0.3962644040584564),
 ('Sin', 0.36455491185188293),
 ('blanc', 0.3636135756969452),
 ('Géant', 0.3622574210166931),
 ('Route', 0.3602677285671234),
 ('Gardien', 0.35134968161582947),
 ('Puissance', 0.3466736972332001),
 ('Elfe', 0.3355366587638855),
 ('équipement', 0.3334060609340668),
 ('chauffeur', 0.33207967877388)]

Ensuite, envisageons de visualiser ce résultat. Puisque Word2Vec convertit cette fois les mots en vecteurs à 30 dimensions, il est nécessaire de réduire les dimensions (** réduction de dimension **) afin de représenter graphiquement. «t-SNE» est l'un des modèles d'apprentissage non supervisé qui réduit les dimensions, et il est possible d'agréger des données dans n'importe quelle dimension afin de ne pas laisser tomber les informations (distribution) autant que possible. Envisagez de tracer sur un diagramme de dispersion avec l'axe xy et implémentez le processus de réduction de 30 dimensions en 2 dimensions.

python


#Extraire 200 mots fréquemment utilisés
n=200
topwords = monsters_words["word"].value_counts().head(n)
w2v_vecs = np.zeros((topwords.shape[0],30))
for i, word in enumerate(topwords.index):
    w2v_vecs[i] = model_w2v.wv[word]

    
# t-Réduction de dimension avec SNE: passe de 30 dimensions à 2 dimensions
tsne= TSNE(n_components=2, verbose=1, n_iter=500)
tsne_w2v_vecs = tsne.fit_transform(w2v_vecs)

w2v_x = tsne_w2v_vecs[:, 0]
w2v_y = tsne_w2v_vecs[:, 1]

Étant donné que chaque mot a des données vectorielles bidimensionnelles, dessinez un diagramme de dispersion en prenant chacun sur les axes x et y. Si les informations des données originales restent même après la réduction de dimension, il devrait être possible d'interpréter que les mots les plus proches les uns des autres ont des significations similaires. À première vue, le résultat de l'intrigue semble que les mots sont disposés au hasard, mais il peut également être considéré comme ayant une signification similaire à celle illustrée ci-dessous.

nlp6-1.png

python


df4visual = pd.DataFrame({"word":topwords.index, "x":w2v_x, "y":w2v_y})
f, ax = plt.subplots(figsize=(20, 20))
ax = sns.regplot("x","y",data=df4visual,fit_reg=False, scatter_kws={"alpha": 0.2})
for i, text in enumerate(topwords.index):
    ax.text(df4visual.loc[i, 'x'], df4visual.loc[i, 'y'], text)
ax.axis("off")
ax.set_title("Visualisation de la similitude de 200 mots qui apparaissent fréquemment dans les titres des cartes")
plt.savefig('./output/nlp6-1.png', bbox_inches='tight', pad_inches=0)

5-2. Doc2Vec

Tandis que «Word2Vec» acquiert l'expression distribuée des mots, «Doc2Vec» peut acquérir l'expression distribuée des phrases en ajoutant la phrase à laquelle le mot appartient comme information de balise au moment de l'apprentissage. Cela vous permet de mesurer la signification entre les phrases (noms de cartes) et ensuite le parapluie.

Comme préparation préliminaire, créez un TaggedDocument comme entrée du modèle. Attribuez le nom de la carte que le mot compose à la liste de mots en tant que balise.

python


document = [TaggedDocument(words = wordlist, tags = [monsters_wordlist.name[i]]) for i, wordlist in enumerate(monsters_wordlist.wordlist)]
document[0]
TaggedDocument(words=['A', 'BF', 'Pluie de mai', 'Sohaya'], tags=['A BF-Pluie de maiのSohaya'])

La méthode d'apprentissage est presque la même que «word2vec». La méthode d'apprentissage «dm» est définie sur la valeur par défaut 0, le nombre de dimensions «vector_size» est défini sur 30 et le nombre de répétitions «epochs» est défini sur 200. À propos, 1 époque signifie saisir une fois tous les mots de l'ensemble de données.

python


%time model_d2v = Doc2Vec(documents = document, dm = 0, vector_size=30, epochs=200)

Lançons le test de la même manière. Utilisez la méthode docvecs.most_similar () pour vérifier les premiers noms de cartes similaires avec le nom de la carte comme entrée. Quand je suis entré dans "Black Magician", la Black Magician Girl est revenue à la 1ère place. Puisque les noms de cartes utilisant le même mot suivent, il semble que l'apprentissage se fasse presque correctement!

python


model_d2v.docvecs.most_similar("magicien noir")
[('Fille de magicien noir', 0.9794564843177795),
 ('Magicien noir Toon', 0.9433020949363708),
 ('Fille de magicien noir Toon', 0.9370808601379395),
 ('Dragon Knight Black Magician', 0.9367024898529053),
 ('Dragon Knight Black Magician Girl', 0.93293297290802),
 ('Taureau noir Drago', 0.9305672645568848),
 ('Magicien de l'illusion noire', 0.9274455904960632),
 ('Magicien astrographe', 0.9263750314712524),
 ('Magicien du chronographe', 0.9257084727287292),
 ('Magicien du disque', 0.9256418347358704)]

La réduction de dimension est également effectuée de la même manière que «word2vec», et 200 cartes sont sélectionnées au hasard pour la visualisation. Des mots similaires viennent presque dans la même position, ce qui le rend un peu difficile à voir. .. Cependant, vous pouvez voir que les noms de cartes avec le même mot sont dispersés à proximité.

nlp6-2.png

python


d2v_vecs = np.zeros((monsters_wordlist.name.shape[0],30))
for i, word in enumerate(monsters_wordlist.name):
    d2v_vecs[i] = model_d2v.docvecs[word]

tsne = TSNE(n_components=2, verbose=1, n_iter=500)
tsne_d2v_vecs = tsne.fit_transform(d2v_vecs)

d2v_x = tsne_d2v_vecs[:, 0]
d2v_y = tsne_d2v_vecs[:, 1]

monsters_vec = monsters_wordlist.copy()
monsters_vec["x"] = d2v_x
monsters_vec["y"] = d2v_y

df4visual = monsters_vec.sample(200, random_state=1).reset_index(drop=True)
f, ax = plt.subplots(figsize=(20, 20))
ax = sns.regplot("x","y",data=df4visual, fit_reg=False, scatter_kws={"alpha": 0.2})
for i, text in enumerate(df4visual.name):
    ax.text(df4visual.loc[i, 'x'], df4visual.loc[i, 'y'], text)
ax.axis("off")
ax.set_title("Visualisation de la similitude de 200 monstres")
plt.savefig('./output/nlp6-2a.png', bbox_inches='tight', pad_inches=0)

Comme c'est un gros problème, je tracerai toutes les cartes sans nom de carte. Ce qui suit est un diagramme de dispersion illustrant la proximité (vecteur) de la signification de toutes les cartes, peintes par race. Je pense que c'était un excellent résultat! Le groupe circulaire en bas du graphique peut être déduit comme étant une collection de cartes sans série. Les cartes sont peu dispersées autour d'elle, mais vous pouvez probablement voir qu'elles forment un petit groupe dans la même série.

nlp6-2b.png

python


df4visual = monsters_vec
g = sns.lmplot("x","y",data=df4visual, fit_reg=False, hue="attr", height=10)
g.ax.set_title("Distribution de la proximité de la signification de tous les noms de cartes")

Par exemple, il existe un groupe d'attributs Terre autour des coordonnées (x, y) = (-40, -20). Si vous recherchez ces informations avec une requête, vous constaterez qu'il s'agit d'une collection de la série "Ancient Machines". se sentir bien!

python


monsters_vec.query("-42 <= x <= -38 & -22 <= y <= -18")["name"]
2740 Roi machine parfait
3952 Ancien guerrier lézard
3953 Ancien soldat mécanique
3954 Ancienne bête mécanique synthétique
3955 Dragon synthétique mécanique antique
3956 Ancien mécanicien
3957 Géant mécanique antique
3958 Ancienne livre mécanique géante ultime
3959 Ancien dragon géant mécanique
3960 Géant du chaos mécanique antique
3961 Ancien dragon thermonucléaire mécanique
3962 Chien de chasse mécanique antique
3963 Ancienne bête mécanique
3964 Tourelle mécanique ancienne
3965 Géant ultime de la machine antique
3966 Boîte de machine ancienne
3967 Corps mécanique ancien
3968 Ancien super géant mécanique
3969 Ancien dragon volant mécanique
3970 Ancien chevalier mécanique
3971 Génie mécanique antique
3972 Équipement ancien
3973 Ancienne machine à engrenages
3974 Ancien mage
4036 Plaque de Gaia géante de la Terre
4279 Lunettes géantes
4491 Machine de torture à lame pendulaire
4762 soldats mécaniques
4764 Chien machine Maron
4765 Roi Machine
4766 Machine King-Prototype
4767 Outil électrique Dragon mécanique
4768 Sergent mécanique
4994 Géant de lave
5247 Zushin géant endormi
5597 Monstre super ancien

Enfin, vérifions la similitude par attribut, race et niveau, pas par nom de carte. Les vecteurs obtenus pour chaque carte sont moyennés pour chaque attribut, race et niveau, et tracés pour chaque coupe de chaque donnée.

** Par attribut **

Seul l'attribut d'obscurité a été mappé à un endroit qui était désagréable.

nlp6-2c.png

python


df4visual = monsters_vec.groupby("attr").mean()[["x", "y"]].reset_index().query("attr != 'Attribut de Dieu'").reset_index(drop=True) # Attribut de Dieuは外れ値になるため省略する
f, ax = plt.subplots(figsize=(10, 10))
ax = sns.regplot("x","y",data=df4visual, fit_reg=False, scatter_kws={"alpha": 0.2})
for i, text in enumerate(df4visual.attr):
    ax.text(df4visual.loc[i, 'x'], df4visual.loc[i, 'y'], text)

ax.set_title("Visualisation de la similitude des noms de cartes par attribut")
plt.savefig('./output/nlp6-2c.png', bbox_inches='tight', pad_inches=0)

** Par race **

Si vous essayez de le forcer, les poissons et les reptiles sont proches les uns des autres.

nlp6-2d.png

python


df4visual = monsters_vec.groupby("species").mean()[["x", "y"]].reset_index().query("species != 'Dieux créatifs' & species != 'Bête fantôme'").reset_index(drop=True) #L'attribut race of the god est omis car il s'agit d'une valeur aberrante.
f, ax = plt.subplots(figsize=(15, 15))
ax = sns.regplot("x","y",data=df4visual, fit_reg=False, scatter_kws={"alpha": 0.2})
for i, text in enumerate(df4visual.species):
    ax.text(df4visual.loc[i, 'x'], df4visual.loc[i, 'y'], text)
ax.axis("on")
ax.set_title("Visualisation de la similitude des noms de cartes par race")
plt.savefig('./output/nlp6-2d.png', bbox_inches='tight', pad_inches=0)

** Par niveau **

Vous pouvez voir que la bande de bas niveau (1 ~ 4) est assez proche. Même dans la bande de haut niveau, 10 et 11 sont proches, mais 12 sont très éloignés, on peut donc en déduire qu'ils ont des caractéristiques de nom différentes.

nlp6-2e.png

python


df4visual = monsters_vec.groupby("level").mean()[["x", "y"]].reset_index().query("level != '0'").reset_index(drop=True) #Le niveau 0 est une valeur aberrante, alors omettez-le
f, ax = plt.subplots(figsize=(10, 10))
ax = sns.regplot("x","y",data=df4visual, fit_reg=False, scatter_kws={"alpha": 0.2})
for i, text in enumerate(df4visual.level):
    ax.text(df4visual.loc[i, 'x'], df4visual.loc[i, 'y'], text)

ax.set_title("Visualisation de la similitude des noms de cartes par niveau")
plt.savefig('./output/nlp6-2e.png', bbox_inches='tight', pad_inches=0)

Résumé

Merci d'avoir lu jusqu'ici. Pour approfondir encore le nom de la carte Yugioh, nous avons effectué une série d'analyses de l'analyse morphologique par «Mecab», de la visualisation par «WordCloud» et de l'acquisition de l'expression distribuée par «Word2Vec» et «Doc2Vec». Je pense que le diagramme de dispersion de toutes les cartes de Doc2Vec me plaît. Dans la partie apprentissage automatique du processus suivant, les fonctionnalités obtenues ici seront utilisées telles quelles, nous espérons donc être en mesure de créer un modèle de prédiction très précis.

Aperçu de la prochaine fois

C'est enfin l'apprentissage automatique. Je ne l'ai pas encore implémenté et je pense au thème, mais j'aimerais construire le modèle de prédiction suivant en général. Veuillez attendre avec impatience.

  1. Prédisez la puissance offensive, la puissance défensive, les attributs, les races, etc. à partir de n'importe quel nom de carte avec Doc2Vec et LightGBM
  2. Générez un nom de carte avec LSTM (cela peut être omis en raison de contraintes de temps ...)

Recommended Posts

Traiter le nom de la carte Yugioh en langage naturel --Yugiou Data Science 2. PNL
Python: traitement du langage naturel
RNN_LSTM2 Traitement du langage naturel
Insoutenable manque d'attention dans le traitement du langage naturel
Vérification des performances du prétraitement des données dans le traitement du langage naturel
Traitement du langage naturel 1 Analyse morphologique
Traitement du langage naturel 3 Continuité des mots
Vue d'ensemble du traitement du langage naturel et de son prétraitement des données
Traitement du langage naturel 2 similitude de mots
Types de prétraitement dans le traitement du langage naturel et leur puissance
■ [Google Colaboratory] Prétraitement du traitement du langage naturel et janome
Étudiez le traitement du langage naturel avec Kikagaku
Traitement du langage naturel pour les personnes occupées
[Traitement du langage naturel] Prétraitement avec le japonais
Logivan du langage artificiel et traitement du langage naturel (traitement du langage artificiel)
100 traitement du langage knock-59: analyse de la formule S
Se préparer à démarrer le traitement du langage naturel
Résumé de l'installation de l'analyseur de traitement du langage naturel
Résumé du traitement multi-processus du langage de script
Pourquoi l'expression distribuée des mots est-elle importante pour le traitement du langage naturel?
[Word2vec] Visualisons le résultat du traitement en langage naturel des avis des entreprises
Réponses et impressions de 100 chocs de traitement linguistique - Partie 1
100 traitement du langage knock-91: Préparation des données d'analogie
Traitement du langage 100 knocks-44: Visualisation des arbres dépendants
100 traitement de langue knock-22: Extraction du nom de la catégorie
Réponses et impressions de 100 chocs de traitement de la langue - Partie 2
100 Knocking Natural Language Processing Chapitre 1 (Mouvement préparatoire)
100 Language Processing Knock-26: suppression du balisage accentué
3. Traitement du langage naturel par Python 2-1. Réseau de co-occurrence
[WIP] Pré-traitement des notes dans le traitement du langage naturel
3. Traitement du langage naturel par Python 1-1. Word N-gram
J'ai essayé le traitement du langage naturel avec des transformateurs.
Mémo de produits pratique autour du traitement du langage naturel
Remplissage facile des données pouvant être utilisées dans le traitement du langage naturel
Apprenez les bases de la classification de documents par traitement du langage naturel, modèle de sujet
100 coups de traitement linguistique (2020): 40
100 coups de traitement linguistique (2020): 32
3. Traitement du langage naturel par Python 2-2. Réseau de co-occurrence [mecab-ipadic-NEologd]
100 coups de traitement linguistique (2020): 35
100 coups de traitement linguistique (2020): 47
100 coups de traitement linguistique (2020): 39
100 coups de traitement linguistique (2020): 22
100 coups de traitement linguistique (2020): 26
100 coups de traitement linguistique (2020): 34
100 coups de traitement linguistique (2020): 28
100 coups de traitement linguistique (2020): 42
100 coups de traitement linguistique (2020): 29
100 coups de traitement linguistique (2020): 49
Le traitement de 100 langues frappe 06 ~ 09
100 coups de traitement linguistique (2020): 43
100 coups de traitement linguistique (2020): 24
[Python] J'ai joué avec le traitement du langage naturel ~ transformers ~
100 coups de traitement linguistique (2020): 45
100 Language Processing Knock-32 (utilisant des pandas): Prototype de verbe
100 coups de traitement linguistique (2020): 10-19
100 coups de traitement linguistique (2020): 30
Traitement du langage 100 knocks-45: Extraction de modèles de cas verbaux
Python: apprentissage profond du traitement du langage naturel: principes de base
100 coups de traitement linguistique (2020): 00-09
100 coups de traitement linguistique (2020): 31