[PYTHON] Clustering des livres d'Aozora Bunko avec Doc2Vec

J'essaierai de trouver un travail similaire à partir des célèbres ouvrages publiés dans Aozora Bunko. J'utiliserai Doc2Vec pour la mise en œuvre. Note) Bien que le titre dise clustering, il ne s'agit pas strictement de clustering, n'est-ce pas?

Qu'est-ce que Doc2Vec?

Doc2Vec est une extension de l'idée de Word2Vec et utilise un vecteur de paragraphe (id de phrase) en plus du vecteur de mot. Pour comprendre Doc2Vec, je me suis référé à la page suivante. https://benrishi-ai.com/doc2vec01/ https://kento1109.hatenablog.com/entry/2017/11/15/181838 De plus, lors de la mise en œuvre de Doc2Vec, je me suis référé à la page suivante. https://qiita.com/g-k/items/5ea94c13281f675302ca Cet article qiita a également brièvement expliqué sur Doc2Vec, Je ne savais pas ce qu'était un vecteur de paragraphe (id de phrase). Je pense que c'est un vecteur qui est la somme de tous les vecteurs de mots qui apparaissent dans ce paragraphe. Vous devez lire et étudier le document Doc2Vec! C'est une autre opportunité! Cette fois, il est mis en œuvre!

Début de la mise en œuvre

Cette fois, je vais gratter les œuvres d'Aozora Bunko pour obtenir les phrases, et je chercherai les œuvres proches de "Human Disqualification" d'Osamu Tadashi à partir des œuvres d'Aozora Bunko.

#Importer les bibliothèques requises
from bs4 import BeautifulSoup
import requests
import jaconv
from gensim import corpora
from gensim import models
from pprint import pprint
import pandas as pd
import string
import MeCab
import unicodedata
from gensim.models.doc2vec import Doc2Vec, TaggedDocument

Spécification du dictionnaire et définition de la fonction

Il est difficile de spécifier le dictionnaire de mecab à chaque fois, alors spécifiez-le d'abord. De plus, il est bon d'organiser le code en définissant le code comme une fonction.

Désignation du dictionnaire

#Spécifiez NEologd dans le dictionnaire MeCab.
#mecab est pour l'analyse des éléments mobiles, wakati est pour le partage
mecab = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/')
wakati = MeCab.Tagger("-Owakati -d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/")

Définition des fonctions

#Définir une fonction pour effectuer une analyse morphologique
#Lorsque vous entrez un fichier, il génère le fichier et lorsque vous transmettez une chaîne de caractères, il renvoie une chaîne de caractères. Changez avec le fichier d'arguments.
#Si vous voulez juste séparer, mecab comme argument=Ceci peut être réalisé avec wakati.
def MecabMorphologicalAnalysis(path='./text.txt', output_file='wakati.txt', mecab=mecab, file=False):
    mecab_text = ''
    if file:
        with open(path) as f:
            for line in f:
                mecab_text += mecab.parse(line)
        with open(output_file, 'w') as f:
            print(mecab_text, file=f)
    else:
        for path in path.split('\n'):
            mecab_text += mecab.parse(path)
        return mecab_text
    

#Puisque les caractères symboliques interfèrent avec l'analyse, nous définissons une fonction qui supprime le symbole.
#Aozora illustré ci-dessous_Utilisé dans la fonction de table.
def symbol_removal(soup):
    soup = unicodedata.normalize("NFKC", soup)
    exclusion = """ "" [],. ・" + "\n" + "\r" + "\u3000"
    soup = soup.translate(str.maketrans("", "", string.punctuation  + exclusion))
    return soup


#Définissez une fonction qui extrait les informations de la bibliothèque Blue Sky et les met en forme en données de table.
#Renvoie le nombre de titres spécifié dans l'argument.(La valeur par défaut est 30)  
#Symbole à l'intérieur_J'utilise la fonction de suppression.
def Aozora_table(n=30):
    url = "https://www.aozora.gr.jp/access_ranking/2019_xhtml.html"
    res = requests.get(url)
    res.encoding = 'shift-jis'
    soup = BeautifulSoup(res.content, "html.parser")

    url_list = [url["href"] for i, url in enumerate(soup.find_all("a", target="_blank")) if i < n]

    title = []
    category = []
    text = []
    for url in url_list:
        res = requests.get(url)
        url_start = url[:37]
        res.encoding = 'shift-jis'
        soup = BeautifulSoup(res.content, "html.parser")
        for i, a in enumerate(soup.find_all("a")):
            if i == 7:
                url_end = a["href"][1:]
        url = url_start + url_end
        res = requests.get(url)
        res.encoding = 'shift-jis'
        soup = BeautifulSoup(res.content, "html.parser")
        title.append(soup.find("h1").string)
        category.append(soup.find("h2").string)
        for tag in soup.find_all(["rt", "rp"]):
            tag.decompose()
        soup = soup.find("div",{'class': 'main_text'}).get_text()
        text.append(symbol_removal(soup))
    df = pd.DataFrame({'title': title, 'category': category, 'text': text})
    return df


#TF en passant une liste de mots à deux niveaux-Obtenez une liste unique de mots triés par IDF.
def sortedTFIDF(sentences):
    
    #Joindre l'ID au mot.
    dictionary = corpora.Dictionary(sentences)
    
    #Comptez le nombre d'apparitions de mots pour chaque œuvre
    corpus = list(map(dictionary.doc2bow, sentences))
    
    #TF pour chaque mot-Calculer IDF
    test_model = models.TfidfModel(corpus)
    corpus_tfidf = test_model[corpus]
    
    # ID:TF-IDF → TF-IDF:Convertissez-vous en mots. TF-TF utilisant trié en amenant IDF vers la gauche-Vous pouvez trier par IDF.
    texts_tfidf = []
    for doc in corpus_tfidf:
        text_tfidf = []
        for word in doc:
            text_tfidf.append([word[1], dictionary[word[0]]])
        texts_tfidf.append(text_tfidf)
    
    # TF-Tri basé sur IDF.
    sorted_texts_tfidf = []
    for text in texts_tfidf:
        sorted_text = sorted(text, reverse=True)
        sorted_texts_tfidf.append(sorted_text)

    return sorted_texts_tfidf

Créer une table de données

Tout d'abord, créez une bable de données en grattant la page d'Aozora Bunko. Utilisez votre propre «fonction Aozora_table» pour créer la table de données.

df = Aozora_table(50)
df.head()
title category text
0 [Ame Nimomakezu] Kenji Miyazawa Pluie Nimomakezu style Nimomakezu Neige Nimo Natsu no Hatsu Sanimo Makenu Durable Nakarada Womochi 慾 Hanaku decision Shite 瞋 Razuitsumo ...
1 Exécutez Meros Osamu Tadashi Melos décide de se débarrasser du roi en colère de la violence méchante, et Melos ne comprend pas la politique ...
2 Yamatsukiki Atsushi Nakajima Li Zhao de Xinxi a été complété par le lieutenant Gangnam au jeune âge du talentueux intellectuel Tianbao.
3 cœur Soseki Natsume Kami-sensei et Iichi J'avais l'habitude d'appeler cette personne un enseignant, alors même ici, écrivez simplement "enseignant" et tapez le vrai nom ...
4 Rashomon Ryunosuke Akutagawa Un jour, un serviteur attendait la pluie sous le Rashomon. Sous la large porte, cet homme était ...

Si le texte est Katakana, il ne peut pas être bien analysé, il sera donc converti en pseudonyme simple.

for i in range(len(df)):
    if df['title'][i] in ["[Ame Nimomakezu]", "Denden Musino Kanashimi"]:
        df['text'][i] = jaconv.kata2hira(df['text'][i])
df.head()
title category text
0 [Ame Nimomakezu] Kenji Miyazawa J'ai un corps solide qui peut résister à la pluie, au vent, à la neige et à la chaleur de l'été, et je ne le regarde jamais.
1 Exécutez Meros Osamu Tadashi Melos décide de se débarrasser du roi en colère de la violence méchante, et Melos ne comprend pas la politique ...
2 Yamatsukiki Atsushi Nakajima Li Zhao de Xinxi a été complété par le lieutenant Gangnam au jeune âge du talentueux intellectuel Tianbao.
3 cœur Soseki Natsume Kami-sensei et Iichi J'avais l'habitude d'appeler cette personne un enseignant, alors même ici, écrivez simplement "enseignant" et tapez le vrai nom ...
4 Rashomon Ryunosuke Akutagawa Un jour, un serviteur attendait la pluie sous le Rashomon. Sous la large porte, cet homme était ...

J'ai réussi à créer une table de données pour Aozora Bunko.

Pré-traitement pour passer au modèle Doc2Vec

Utilisez votre propre fonction d'analyse morphologique Mecab pour l'écrire séparément.

texts = []
for i in range(len(df)):
    texts.append(MecabMorphologicalAnalysis(df['text'][i], mecab=wakati))
#Vérifiez si vous avez terminé la division. Afficher 5 œuvres.
for i, text in enumerate(texts):
    if i < 5:
        display(text[:100])

«Ni la pluie, le vent, la neige, la chaleur de l'été, ni la chaleur de l'été. "Meros était en colère et il a décidé qu'il devait se débarrasser du roi de la violence méchante. Melos ne comprenait pas la politique." «Lee Zhao de Xinxi était un jeune étudiant du talent universitaire Tianbao, et son nom a été ajouté à Tora Ei, puis il a été complété par le lieutenant Gangnam. "Kami-sensei et Iichi, j'avais l'habitude d'appeler cette personne un enseignant, donc même ici, je ne peux pas confesser mon vrai nom simplement en l'écrivant en tant qu'enseignant. C'est un refrain du monde." "Le mode de vie d'un jour, un serviteur attendait la pluie sous Rashomon. Sous la large porte, il n'y avait personne d'autre que cet homme."

J'ai pu écrire les minutes normalement.

Puis convertissez le texte séparé en une liste.

#Convertir en liste
sentences = []
for text in texts:
    text_list = text.split(' ')
    sentences.append(text_list)

Apprentissage de modèle

Maintenant que le prétraitement est terminé et que nous avons les phrases de liste séparées, nous pouvons le transmettre à Doc2Vec pour l'entraînement.

#Tout d'abord, créez des documents et transmettez-les au modèle.
documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(sentences)]
model = Doc2Vec(documents, vector_size=100, window=7, min_count=1)
#Le contenu des documents passés au modèle est une liste correspondant au numéro et au corps. L'auteur est également montré ici pour référence.
for i, doc in enumerate(documents):
    print(doc[1], df['title'][i], df['category'][i], doc[0][:8])

[0] [Ame Nimomakezu] Kenji Miyazawa [«Pluie», «ni», «mo», «bonus», «zu», «vent», «ni», «mo»] [1] Exécutez Meros Osamu Tadashi ['Meros', 'ha', 'rage', 'shi', 'ta', 'must', 'or', ''] [2] Yamatsukiki Atsushi Nakajima [«Shinsai», «», «Lee», «est», «Talent académique», «Tenho», «», «Fin»] [3] Kokoro Natsume Soseki ['supérieur', 'enseignant', 'et', 'je', 'un', 'je', 'est', 'cela'] [4] Rashomon Ryunosuke Akutagawa ['Un jour', '', 'Vivre', '', 'Choses', 'de', 'Sont', 'Seul'] [5] Galaxy Railroad Night Kenji Miyazawa [«Un», «Après-midi», «», «Classe», «de», «est», «Tout le monde», «est»] [6] Disqualification humaine Osamu Tadashi ['Préface', 'Je', 'est', 'Cela', 'Homme', '', 'Photo', '] [7] Je suis un chat Soseki Natsume [«Je», «Je suis un chat», «Nom», «est», «encore», «pas», «où», «de»] [8] Yamanashi Kenji Miyazawa [«Petit», «Tanigawa», «», «Bas», «vers», «Copier», «Ta», «Deux»] [9] Yume Toya Natsume Soseki [«Non», «Un», «Nuit», «Tel», «Rêve», «wa», «Voir», «Ta»] [10] Kusamakura Natsume Soseki [«Ichi», «Yamaji», «vers», «Grimper», «Pendant», «Ko», «Penser», «Ta»] [11] Kenji Miyazawa, un restaurant avec beaucoup de commandes [«Deux personnes», «», «Jeune», «Gentleman», «Ga», «Complètement», «Angleterre», «»] [12] Fil d'araignée Ryunosuke Akutagawa [«Un», «Un jour», «», «Choses», «de», «Sont», «Masu», «Shaka»] [13] Bocchan Natsume Soseki ['Ichi', 'Parental', '', 'Mugun', 'de', 'Kosuke', '', 'Time'] [14] Citron Kajii Motojiro ['Etai', '', 'Savoir', 'Non', 'Ominous', 'Na', 'Messe', 'Ga'] [15] Dogura Magura Hisaku Yumeno ['Page', '', 'Gauche et Droite', 'Centre', 'Intro', 'Chanson', 'Fœtale', 'Yo'] [16] Chieko Sho Kotaro Takamura ['Personnes', 'à', 'Non', 'Na', 'N', 'Est', 'Vous', ''] [17] Hojoki Kamo Chomei [«Allez», «Rivière», «», «Nagare», «est», «En continu», «Shi», « [18] Recommandation pour apprendre Satoshi Fukuzawa ['First', 'Hen', 'Heaven', 'is', 'People', '', 'above', 'to'] [19] «Printemps et Shura» Kenji Miyazawa ['Page', '', 'Gauche et Droite', 'Centre', 'Mentale', 'Sketsuchi', 'Printemps et Shura', 'Taisho'] [20] Appel à se faufiler [21] Maihime Mori Kogai [«Charbon», «O», «Ba», «Hayaya», «Empilement», «Fin», «Tsu», «Moyen»] [22] Yodaka no Hoshi Kenji Miyazawa ["yo", "da", "ka", "est", "vraiment", "difficile à voir", "oiseau", "est"] [23] Momotarou Masao Kusuyama ['Ichi', 'Il était une fois', 'Il était une fois', 'Sont', 'Tokoro', 'à', 'Grand-père', 'et'] [24] Sous le cerisier, Motojiro Kajii [«Sous le cerisier», «cadavre», «est», «enterré», «te», «est», «ceci», «est»] [25] Nankichi Niimi pour acheter des gants [«froid», «hiver», «ga», «nordique», «de», «renard», «», «parent et enfant»] [26] Ryunosuke Akutagawa ['Zen', 'Chinai', 'Supplément', '', 'Nez', 'et', 'Dites', 'Ba'] [27] Takase Funa Mori Kogai ['Takase Funa', 'ha', 'Kyoto', '', 'Takasegawa', 'to', 'up and down', 'do'] [28] Une poignée de sable Ishikawa Tatsuki ['Hakodate', 'Naru', 'Ikurain', 'Miyazaki', 'Daishiro', 'Kimi', 'Country', ''] [29] Journal de Tosa Kinukiyuki ["Homme", "Mo", "Su", "Naru", "Journal", "Toifu", "Choses", "] [30] Chanson Star Tour Kenji Miyazawa ['Akai', 'Medama', '', 'Sasori', 'Hiroge', 'Ta', 'Washi', '' '] [31] Lettre dans le tonneau de ciment Yoshiki Hayama [«Matsudo», «Yozo», «est», «Ciment», «Ake», «to», «Ya», «Te»] [32] Girl Hell Hisaku Yumeno [«Quoi», «N», «Dans», «Non», «Non», «Shirataka», «Hidemaru», «Frère»] [33] Shayo Tadashiji [«Ichi», «Petit déjeuner», «Faire», «à», «Suup», «O», «Ichi», «Soji»] [34] Kawado Ryunosuke Akutagawa ['S'il vous plaît', 'Kappa', 'et', 'Phrase', 'S', ' [35] Otsubel et l'éléphant Kenji Miyazawa [«sont», «vache», «gardien», «Ga», «Monogataru», «premier», «un», «dimanche»] [36] Sakutaro Hagiwara aboyant dans la lune [«Frère», «Hagiwara», «Eiji», «M.», «À», «Dédié», «Introduction», «Hagiwara»] [37] Kaze no Matasaburo Kenji Miyazawa [«Dodo», «Dodo», «Dodo», «Dodo», «Blue», «Kurumi», «Mo», «Blow off»] [38] Gauche jouant du violoncelle Kenji Miyazawa [«Gauche», «wa», «ville», «», «photo d'activité», «kan», «de», «violoncelle»] [39] Sanshiro Natsume Soseki ['Ichi', 'Somnolence', 'As', 'Yeux', 'Ga', 'Sameru', 'et', 'Femme'] [40] Changement d'enfer Ryunosuke Akutagawa ['Ichi', 'Horikawa', '', 'Large', 'Den-sama', '', 'Yau', 'Na'] [41] Écolière Osamu Tadashi ['A', 'Sa', 'Eye', ',' Sa ',' When ',' ',' Feeling '] [42] Navire artisanal de crabe Takiji Kobayashi [«Ichi», «Hey», «Hell», «Sa», «Gogun», «Da», «De», «Two people»] [43] Denden Musino Kanashimi Niimi Nankichi [«Quand», «Piki», «», «Dendenmushi», «ga», «Oui», «Mashi», «Ta»] [44] Galaxy Railroad Night Kenji Miyazawa [«Je», «Après-midi», «», «Classe», «de», «est», «tout le monde», «est»] [45] Moriko Haru Ryunosuke Akutagawa ['Ichi', 'Ou', 'Printemps', '', 'Higurashi', 'Est', 'Tang', '' [46] À Yasunari Kawabata Osamu Tadashi [«Vous», «est», «Bungei Haruaki», «Septembre», «Numéro», «à», «Je», «à»] [47] Yin Hou Rei San Junichiro Tanizaki [«○», «Aujourd'hui», «Contrat public», «Doraku», «», «Personnes», «Ga», «Juin»] [48] Chaise humaine Ranpo Edogawa [«Yoshiko», «wa», «tous les matins», «mari», «», «aller au bureau», «à», «voir»] [49] Camion Ryunosuke Akutagawa [«Odawara», «Atami», «Entre», «à», «Chemin de fer léger», «Pose», «», «Construction»]

Faire des prédictions à l'aide d'un modèle entraîné

Maintenant, utilisons le modèle appris pour extraire des œuvres proches de la «disqualification humaine» de Tadashi Osamu.

#6 est la «disqualification humaine» d'Osamu Tadashi.
#Cela a dû être une histoire de souffrance en se perdant dans ma vie.
#À la fin, j'ai été envoyée dans un hôpital psychiatrique, et j'ai eu l'impression que ça finissait par être lourd.
ranking = model.docvecs.most_similar(6, topn=50)
ranking[:5] #Top 5 fonctionne avec une similitude cosinus élevée
[(14, 0.9827772974967957),
 (1, 0.9771202802658081),
 (46, 0.9766896367073059),
 (48, 0.975338876247406),
 (4, 0.9737432599067688)]
ranking[-5:] #Top 5 fonctionne avec une faible similitude cosinus
[(5, 0.861607551574707),
 (32, 0.8596963882446289),
 (44, 0.8453813195228577),
 (22, 0.8167744874954224),
 (37, 0.8134371042251587)]

Le travail le plus similaire à "Human Disqualification" est sorti sous le nom de "Lemon". C'est certainement proche. J'ai le sentiment que c'était un système dans lequel le personnage principal vivait tout en souffrant, comme dans le cas de la «disqualification humaine». Les 2e et 3e places étaient «Run Meros» et «To Yasunari Kawabata». Les deux sont des œuvres d'Osamu Tadashi! L'ambiance lourde de "Rashomon" à la 5e place n'est-elle pas assez proche de la "disqualification humaine"? ??

La plupart des œuvres qui ne sont pas similaires sont des œuvres de Kenji Miyazawa. (Pour une raison quelconque, "Galaxy Railroad Night" apparaît deux fois) "Galaxy Railroad Night" et "Yodaka no Hoshi" peuvent inquiéter le personnage principal, mais ils ont dû être en quelque sorte chaleureux. .. J'ai l'impression que l'atmosphère est assez différente de la «disqualification humaine».

Nous avons obtenu de bons résultats qui ressemblaient à nos sentiments! Cependant, je me demande honnêtement si toutes les œuvres sont trop proches les unes des autres et peuvent être regroupées correctement.

Considérant l'utilisation de TF-IDF

Alors utilisons TF-IDF pour ne regrouper que les mots importants! !! Voici les avantages et inconvénients attendus de l'utilisation de TF-IDF.

mérite

――Le texte contient de nombreux mots fréquemment utilisés et dénués de sens tels que «o» et «ta» de «lancer la balle», et il y a un risque que chaque œuvre ait un vecteur similaire. Je pensais qu'il y en avait. Par conséquent, en se concentrant sur les mots importants avec TF-IDF et en mettant l'accent sur les caractéristiques du travail, il peut être plus facile de regrouper.

Démérite

―― Comme il ne s'agit plus d'une phrase, il peut être difficile de saisir le libellé et la composition de la phrase propres à l'auteur. ―― Puisque les mots sont regroupés, cela peut ne pas être une bonne approche pour les œuvres qui présentent la même expression encore et encore. ――Probablement, dans l'ouvrage intitulé "Run Meros", des mots tels que "Meros" et "Serinuntius" montrent des valeurs élevées pour TF-IDF. Pouvez-vous dire qu'il représente les caractéristiques du texte? J'ai une question.

Je peux penser à plus d'inconvénients que d'avantages, mais je vais l'essayer pour le moment.

Prétraitement TF-IDF

phrases contient une liste de mots qui ont déjà été séparés. Si c'est sous cette forme, vous pouvez obtenir une liste triée de TF-IDF pour chaque travail en la passant à votre propre fonction sortedTFIDF. Ce que nous faisons avec la fonction sortedTFIDF est l'article précédent [" Implémentation de TF-IDF à l'aide de gensim "](https://qiita.com/kei0919/items/1e191964e727b83372c0#df-idf%E3%82%92 % E5% AE% 9F% E8% A1% 8C% E3% 81% 99% E3% 82% 8B% E5% 89% 8D% E3% 81% AE% E6% BA% 96% E5% 82% 99) C'est la même chose que ce que nous faisons dans la partie TF-IDF.

#Vérifiez le contenu des phrases
for i, sentence in enumerate(sentences):
    if i < 5:
        print(sentence[:10])

['Rain', 'ni', 'mo', 'bonus', 'zu', 'wind', 'ni', 'mo', 'bonus', 'zu'] ['Meros', 'wa', 'rage', 'shi', 'ta', 'must', 'ou', '', 'méchanceté', 'violence'] ['Shinsai', '', 'Li', ',' est ',' Gakusei Tadashi ',' Tenho ',' ',' Fin ',' Plus jeune ',' ['On', 'Teacher', 'and', 'I', 'One', 'I', 'is', 'That', 'People', '] ['Un jour', '' ',' Vivre ',' ',' Choses ',' à ',' Là ',' Une personne ',' ',' Homme inférieur ']

#TF en utilisant votre propre fonction sortedTFIDF-Obtenez une liste triée par IDF.
sorted_texts_tfidf = sortedTFIDF(sentences)
#TF pour chaque œuvre-Vérifiez les mots avec un IDF élevé
for i, tfidf in enumerate(sorted_texts_tfidf):
    if i < 5:
        print('%s.' % i, '〜%s〜' % df['title'][i]) #Le titre est également affiché pour le moment
        pprint(tfidf[:10])
        print('')
  1. ~ [Ame Nimomakezu] ~ [[0,5270176717513841, "Nanmu"], [0,335824762232814, "Bonus"], [0,2720937923932906, «Maki»], [0.1360468961966453, '萓'], [0.1360468961966453, "Gravure"], [0.1360468961966453, «Riz brun»], [0.1360468961966453, «Mubeyuki Bosatsu»], [0.1360468961966453, «Jyogyo Bosatsu»], [0.1360468961966453, «Anryu Bodhisattva»], [0.1360468961966453, «Taho Nyorai»]]

  2. ~ Exécutez Meros ~ [[0.8826660798685602, "Meros"], [0.1647643349087979, «Serinuntius»], [0.12468722733644991, "King"], [0,09375235972221699, «je»], [0.07738167204990741, "Vous"], [0.07061328638948482, "Flux boueux"], [0.06778538031378131, "foule"], [0.06439978483773416, "Ami"], [0,06166407227059827, "Non"], [0.05884440532457068, «Nobumi»]]

  3. ~ Yamatsukiki ~ [[0,46018061185481746, '袁'], [0,46018061185481746, «Li Zhen»], [0,32450428070224685, "soi"], [0,2989295156005757, «Mura»], [0.1698659669116043, "tigre"], [0.10946065580700806, "Désolé"], [0.07971453749348684, '吏'], [0.0726600966086554, "Honte"], [0.0726600966086554, "Digne"], [0.07127857508099637, "Fierté"]]

  4. ~ Coeur ~ [[0,5354264061948253, «je»], [0.4564728456651801, 'K'], [0,282595486317482, "épouse"], [0.2504145163549083, "Enseignant"], [0.17885230572329233, "est"], [0.1597103741100704, "Dame"], [0.12084196131850143, "Choses"], [0.11917933998957644, "Père"], [0.11460565741637332, "pas"], [0.10324388965526733, «je»]]

  5. ~ Rashomon ~ [[0,7324117083727154, "Inférieur"], [0.46608017805536434, "Vieille femme"], [0.1618414518545496, "Décès"], [0,1416112703727309, «Rashomon»], [0.1059977890898406, "dire"], [0.10332033314297188, "Mort"], [0.09868036169619741, 'échelle'], [0.0809207259272748, "Face"], [0.07675139243037576, "Épée"], [0.07581439176692739, "Mort"]]

J'ai pu trier par ordre décroissant de TF-IDF. Maintenant, créons une liste ʻall_title` se concentrant sur les 100 premiers mots pour chaque travail et passons-la au modèle Doc2Vec.

all_title = []
for tfidf in sorted_texts_tfidf:
    title = []
    for word in tfidf[:100]: #Réduire à 100 mots
        title.append(word[1])
    all_title.append(title)
# all_Vérifiez le contenu de la liste des titres
for i, text in enumerate(all_title):
    if i < 5:
        print(text[:10])

[«Nanmu», «Faire», «Maki», «萓», «Brûler», «Genmai», «Mubeyuki Bosatsu», «Jyogyo Bosatsu», «Anritsuyuki Bosatsu», «Taho Nyorai»] ['Meros', 'Serinuntius', 'King', 'I', 'You', 'Muddy Stream', 'Crowd', 'Friends', 'No', 'Nobumi'] ['袁', 'Li Zhao', 'Soi', 'Mura', 'Tora', 'Chagrin', '吏', 'Honte', 'Dignité', 'Respect de soi'] [«Je», «K», «épouse», «professeur», «est», «jeune femme», «chose», «père», «pas», «je»] [«Homme inférieur», «Vieille femme», «Mort de la mort», «Rashomon», «Dis», «Corps mort», «Échelle», «Épée de visage», «Épée», «Homme mort»]

Apprenez à nouveau le modèle Doc2Vec

#Liste des mots importants dans le modèle Doc2Vec tous_Passez le titre.
documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(all_title)]
model = Doc2Vec(documents, vector_size=100, window=5, min_count=1)
#Afficher une liste de nombres et fonctionne pour une comparaison facile avec les résultats
for i, doc in enumerate(documents):
    print(doc[1], df['title'][i], df['category'][i], doc[0][:8])

[0] [Ame Nimomakezu] Kenji Miyazawa [«Nanmu», «Make», «Maki», «萓», «Burning», «Genmai», «Mubeyuki Bosatsu», «Jyogyo Bosatsu»] [1] Exécutez Meros Osamu Osamu [«Meros», «Serinuntius», «King», «I», «You», «Muddy Stream», «Crowd», «Friends»] [2] Yamatsukiki Atsushi Nakajima ['袁', 'Li Zhou', 'Soi', 'Mura', 'Tora', 'Chagrin', '吏', 'Honte'] [3] Kokoro Natsume Soseki [«je», «K», «épouse», «professeur», «est», «jeune femme», «chose», «père»] [4] Rashomon Ryunosuke Akutagawa [«Senior», «Vieille femme», «Mort», «Rashomon», «Parlant», «Cadavre», «Échelle», «Visage»] [5] Galaxy Railroad Night Kenji Miyazawa [«Giovanni», «Campanella», «Je suis», «Je», «Mashi», «Galaxy», «Capture», «Heavenly River»] [6] Disqualification humaine Osamu Tadashi [«Horiki», «soi», «hirame», «clown», «deshi», «Yoshiko», «chose», «tsuneko»] [7] Soseki Natsume, qui est un chat [8] Yamanashi Kenji Miyazawa [«Crambon», «Crabe», «Yamanashi», «Wara», «Mousse», «Papa», «Crush», «Kapukapu»] [9] Yume Toya Natsume Soseki [«Shotaro», «Yu», «Vieil homme», «Soi», «Nio», «Cochon», «Je», «Unkei»] [10] Kusamakura Natsume Soseki [«Yo», «Yu», «Kuichi», «Peinture», «Inhumanité», «Nu», «Iru», «Nami»] [11] Kenji Miyazawa, un restaurant avec beaucoup de commandes [«porte», «crème», «moi», «bokura», «arrière», «cliquetis», «s'il vous plaît», «obtenu»] [12] Fil d'araignée Ryunosuke Akutagawa ['Taita', 'Fil d'araignée', 'Oshaka', 'Paradise', 'Blood Pond', 'Are', 'Hell', 'Needle Mountain'] [13] Bocchan Natsume Soseki [«Chemise rouge», «Yamastorm», «I», «Uranari», «Yu», «Kiyo», «Yu», «Principal»] [14] Citron Kajii Motojiro [«Citron», «Je», «Maruzen», «Ville», «Magasin de fruits», «――», «廂», «Peinture»] [15] Dogura Magura Hisaku Yumeno [«Masaki», «Wakabayashi», «Ichiro», «Gozai», «Wu», «Docteur», «Je suis», «Cerveau»] [16] Chieko Sho Kotaro Takamura [«Chieko», «Elle», «Tsute», «Yau», «ゐ», «Atsu», «Toifu», «Tsuta»] ... [18] Recommandations académiques Satoshi Fukuzawa [«Gouvernement», «Peuple», «at», «Beshi», «Bekara», «Zaru», «Ara», «Ou»] [19] "Printemps et Shura" Kenji Miyazawa ['Iru', 'Watakushi', 'Tsute', 'Yau', 'Kai', 'Page', 'Se balançant', '┃'] [20] Soupçon de se faufiler [«je», «Pierre», «cela», «vous», «disciple», «non», «Jérusalem», «parler»] [21] Maihime Mori Kogai ['Yo', 'Eris', 'ゝ', 'at', 'Aizawa', 'Taru', 'I', 'Minister'] [22] Yodaka no Hoshi Kenji Miyazawa ['Hawk', 'Ichizo', 'Nest', 'I', 'Burnt', 'Suzume', 'Star', 'Sora'] [23] Momotaro Masao Kusuyama [«Momotaro», «Grand-mère», «Grand-père», «Kibidango», «Oni ga Shima», «Kiji», «Pêche», «Oni»] [24] Sous le cerisier, Motojiro Kajii [«Je», «cadavre», «溪», «Sous le cerisier», «vous», «enterré», «plume mince», «racine des cheveux»] [25] Nankichi Niimi pour acheter des gants [«Renard enfant», «renard», «Garçon», «Mère», «Mains», «Mère», «Magasin de chapeaux», «Gants»] [26] Ryunosuke Akutagawa ['Offrande interne', 'Moine', 'Nez', 'Disciple', '哂', 'Dis', 'Court', 'Doji'] [27] Takase Funamori Kogai [«Kisuke», «Tsute», «衞», «Sho», «Un», «Départ», «Watakushi», «Ya»] [28] Une poignée de sable Ishikawa Tatsuki ['Ami', 'Furusato', 'Ariki', 'Kanashi', 'Kanashiki', 'Pensée', 'Taru', 'Ramu'] [29] Tosa Diary Kinukiyuki ['ゝ', 'read', 'i', 'ship', 'if', 'keri', 'country', 'song'] [30] Chanson Star Tour Kenji Miyazawa [«Medama», «Petit Inu», «Hebi», «Tsuyu», «Tsubasa», «Shimoto», «Guma no Ashio», «Oguma»] [31] Lettre dans un tonneau de ciment Yoshiki Hayama [«Ciment», «Lover», «Tall», «He», «Masu», «Mixer», «Small Box», «Rip»] [32. [33] Shayo Tadashi [«maman», «Naoji», «je», «Uehara», «je», «oncle», «vous», «O»] [34] Kawado Ryunosuke Akutagawa [«Kawado», «Totsuku», «je», «ゐ», «ゐ», «Tetsu», «Geel», «Un»] [35] Otsubel et éléphant Kenji Miyazawa [«Otsubel», «Éléphant», «Gralaagaa Gralaagaa», «Éléphant blanc», «Hutte», «Tel», «Grip», «I»] [36] Sakutaro Hagiwara aboyant dans la lune [«Yau», «ゐ», «tsute», «tsuta», «poésie», «moi», «ゐ», «atsu»] [37] Kaze no Matasaburo Kenji Miyazawa [«Kasuke», «Saburo», «Ro», «Ichiro», «Matasaburo», «Kosuke», «Say», «Mashi»] [38] Gauche jouant du violoncelle Kenji Miyazawa [«Gauche», «Kakkou», «Sero», «Rakucho», «Tsumugi», «Jouer», «Je dis», «Souris sauvage»] [39] Sanshiro Natsume Soseki [«Ro», «Sanshi», «Yojiro», «Mieko», «Nonomiya», «Sanshiro», «Hirota», «Haraguchi»] [40] Changement de l'enfer Ryunosuke Akutagawa ['Yoshihide', 'Are', 'Ya', 'Tsute', 'Un', 'Den-sama', 'Go', 'Iru'] [41] Écolière Osamu Tadashi [«maman», «je», «Japii», «je», «Imaida», «papa», «Kaa», «sœur»] [42] Navire artisanal de crabe Takiji Kobayashi [«Fisher», «Directeur», «――», «Mais», «Kawasaki», «Tatsu», «Tsu», «Capitaine»] [43] Denden Musino Kanashimi Niimi Nankichi [«Dendemushi», «Amis», «Kanasimi», «Ippai», «I», «Yun», «Iki», «Naka»] [44] Galaxy Railroad Night Kenji Miyazawa [«Giovanni», «Campanella», «I», «Better», «Tenkawa», «Say», «Beyond», «Galaxy»] [45] Moriko Haru Akutagawa Ryunosuke [«Moriko Haru», «Tsute», «ゐ», «ゐ», «Mt. [46] À Yasunari Kawabata Osamu Tadashi [«Hana du clown», «Kazuo Dan», «Frère», «Je», «M.», «Yasunari Kawabata», «Dostoïevski», «Phrase»] [47] Yin-Hai Rei Sanchiro Tanizaki Junichiro ['Uru', 'ゝ', 'Yin-Hai', 'Aro', 'Darkness', 'We', '' ',' I '] [48] Chaise humaine Ranpo Edogawa [«Oui», «Je», «Chaise», «Elle», «Sama», «Masu», «Hôtel», «Femme»] [49] Camion Ryunosuke Akutagawa [«Ryohei», «Trocco», «Terrassement», «Chemin de fer», «――», «Construction», «Il», «Pousser»]

Annonce des résultats!

ranking = model.docvecs.most_similar(6, topn=50) #Cette fois également vérifiée par la «disqualification humaine» d'Osamu Tadashi
ranking[:5]
[(45, 0.25298941135406494),
 (26, 0.22999905049800873),
 (36, 0.1593010127544403),
 (21, 0.15090803802013397),
 (47, 0.1467716097831726)]
ranking[-5:]
[(12, -0.11983974277973175),
 (41, -0.12426283210515976),
 (0, -0.1281222403049469),
 (13, -0.1791403889656067),
 (25, -0.2501679062843323)]

Je regarde les œuvres jugées similaires, mais il n'y a pas d'œuvres qui me semblent similaires. Au contraire, si vous regardez les œuvres jugées non similaires, il semble que l'œuvre de Tadashi est, eh bien, l'ambiance est différente, mais ...

C'est pourquoi j'ai trouvé que l'utilisation de TF-IDF réduit la précision des romans. La raison en est les [inconvénients] mentionnés ci-dessus (https://qiita.com/kei0919/items/bde365bf179c0a1573af#%E3%83%87%E3%83%A1%E3%83%AA%E3%83%83 Je pense que% E3% 83% 88) est impliqué.

C'est frustrant comme c'est, alors j'utiliserai Doc2Vec et TF-IDF pour analyser les articles de presse!

Recommended Posts

Clustering des livres d'Aozora Bunko avec Doc2Vec
Clustering avec python-louvain
Clustering avec scikit-learn (1)
Clustering avec scikit-learn (2)
Faisons résumer Aozora Bunko en discutant avec COTOHA
Estimation de l'auteur à l'aide du réseau neuronal et de Doc2Vec (Aozora Bunko)
[Version 2020] Grattage et traitement du texte d'Aozora Bunko
Clustering avec scikit-learn + DBSCAN
DBSCAN (clustering) avec scikit-learn