[PYTHON] Analysez le modèle thématique pour devenir romancier avec GensimPy3

Il existe une bibliothèque Python qui gère les modèles de sujets appelés gensim. Officiellement, il ne prend en charge que la version 2.5 de Python <= Python <3.0.

Cependant, Samantp a publié une bibliothèque appelée gensimPy3. C'est un fork de gensim pour Python 3.3.

Cette fois, en utilisant ce gensimPy3, c'est le même que celui de Shoto Analyse du classement pour devenir romancier avec un modèle thématique (gensim) J'ai expérimenté pour voir si je pouvais le faire.

Installation de GensimPy3

https://github.com/samantp/gensimPy3

Clonez le code source à partir de.

git clone [email protected]:samantp/gensimPy3.git

alors,

python setup.py test

si tu fais

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa3 in position 3973: invalid start byte

J'étais inquiet parce que j'avais une erreur. Mais je l'ai ignoré et l'ai installé.

python setup.py install

Pour une raison quelconque, j'ai obtenu une SyntaxError, mais l'installation a réussi.

Différences d'environnement

Les différences avec l'article de Shoto http://sucrose.hatenablog.com/entry/2013/04/27/225218 sont décrites ci-dessous.

--Utilisation de Python3.3.1 sur pyenv --gensim utilise gensimPy3 -Utilisez pyquery au lieu de BeautifulSoup --Utilisez requêtes au lieu de urllib2

Étant donné que pyquery peut utiliser le même sélecteur de notation que JQuery, il est facile de faire des essais et des erreurs à l'aide de Console, un outil de développement de Chrome. Pratique.

Code source

topic_model_in_narou.py


# -*- coding: utf-8 -*-
import requests
from pyquery import PyQuery as pq
import gensim
import pdb


def fetch_narou_ranking_html():
    r = requests.get('http://yomou.syosetu.com/rank/list/type/total_total/')
    r.encoding = 'utf-8'
    return r.text


def collect_tags(d):
    d_novels = d('.s')
    tags = []
    for d_novel in d_novels:
        d_tag_name_list = d_novel.findall('a')
        tags_in_a_novel = [d_tag_name.text for d_tag_name in d_tag_name_list]
        tags.append(tags_in_a_novel)
    return tags


if __name__ == "__main__":
    html = fetch_narou_ranking_html()
    d = pq(html.encode('utf-8'))
    tags = collect_tags(d)

    dictionary = gensim.corpora.Dictionary(tags)
    dictionary.filter_extremes(3)
    corpus = [dictionary.doc2bow(text) for text in tags]
    lda = gensim.models.ldamodel.LdaModel(corpus=corpus, num_topics=10, id2word=dictionary)
    for x in lda.show_topics(-1, 5):
        print(x)

J'ai fait un modèle avec ce code et j'ai pu afficher des sujets. Les résultats sont les suivants.

0.115*Fantaisie+ 0.068*la magie+ 0.041*Tricher+ 0.034*Harem+ 0.028*Réincarné
0.173*la magie+ 0.095*Fantaisie+ 0.039*sombre+ 0.033*Voyage+ 0.027*Réincarné
0.106*Réincarné+ 0.087*Harem+ 0.074*Le héros le plus fort+ 0.063*Tricher+ 0.052*Fantaisie
0.079*Fantaisie+ 0.069*Tricher+ 0.062*amour+ 0.059*Réincarné+ 0.041*Un autre tour du monde
0.088*Fantaisie+ 0.063*Un autre tour du monde+ 0.051*Harem+ 0.039*aventure+ 0.039*Inscription au grand prix OVL Bunko
0.105*Tricher+ 0.103*Fantaisie+ 0.062*Le héros le plus fort+ 0.058*la magie+ 0.044*Réincarné
0.099*Fantaisie+ 0.089*Réincarné+ 0.045*Le héros le plus fort+ 0.045*le plus fort+ 0.034*la magie
0.051*la magie+ 0.051*Parvenu+ 0.051*monstre+ 0.039*VRMMO + 0.039*sérieux
0.140*Fantaisie+ 0.077*Tricher+ 0.054*Réincarné+ 0.043*la magie+ 0.038*aventure
0.168*Fantaisie+ 0.073*la magie+ 0.052*amour+ 0.026*aventure+ 0.026*guerre

Ouais, juste de la fantaisie ... Il y a trop de genres identiques et ils ne sont pas divisés en sujets. Il semble préférable d'obtenir les données du roman pixiv.

Postscript

dictionary.filter_extremes (no_below = 5, no_above = 0.5, keep_n = 100000) J'ai pensé qu'il serait possible de changer la situation de fantaisie uniquement en changeant la valeur de la fonction et en filtrant, alors je l'ai modifiée.

topic_model_in_narou.py


# -*- coding: utf-8 -*-
import requests
from pyquery import PyQuery as pq
import gensim
import pdb


def fetch_narou_ranking_html():
    r = requests.get('http://yomou.syosetu.com/rank/list/type/total_total/')
    r.encoding = 'utf-8'
    return r.text


def collect_tags(d):
    d_novels = d('.s')
    tags = []
    for d_novel in d_novels:
        d_tag_name_list = d_novel.findall('a')
        tags_in_a_novel = [d_tag_name.text for d_tag_name in d_tag_name_list]
        tags.append(tags_in_a_novel)
    return tags


if __name__ == "__main__":
    html = fetch_narou_ranking_html()
    d = pq(html.encode('utf-8'))
    tags = collect_tags(d)

    dictionary = gensim.corpora.Dictionary(tags)
    dictionary.filter_extremes(no_below=5, no_above=0.05, keep_n=10000)  #Changement
    corpus = [dictionary.doc2bow(text) for text in tags]
    lda = gensim.models.ldamodel.LdaModel(corpus=corpus, num_topics=20, id2word=dictionary)
    for x in lda.show_topics(-1, 5):
        print(x)

La valeur de no_above a été définie sur 0,05. Nous avons décidé de ne pas compter les tags qui apparaissent dans plus de 5% du total.

Site officiel de gensim http://radimrehurek.com/gensim/corpora/dictionary.html

Voici les résultats.

0.166*croissance+ 0.133*la comédie+ 0.100*bataille+ 0.100*Parvenu+ 0.067*Grand prix Narocon
0.106*SF + 0.054*Voyage+ 0.054*VRMMO + 0.054*Grand prix Narocon+ 0.054*Parvenu
0.142*Dragon+ 0.142*sombre+ 0.073*esclave+ 0.073*Aristocrate+ 0.073*bataille
0.120*sorcier/sorcière+ 0.081*esprit+ 0.081*Elfe+ 0.081*Homme bête+ 0.081*Parvenu
0.136*Courageux+ 0.136*la comédie+ 0.092*Labyrinthe+ 0.092*le plus fort+ 0.092*VRMMO
0.140*Invoquez un autre monde+ 0.106*Nation/Gens+ 0.071*VRMMO + 0.053*adorer+ 0.036*esclave
0.153*Chevalier+ 0.078*Malentendu+ 0.078*moyen Âge+ 0.078*sorcier/sorcière+ 0.078*Invoquez un autre monde
0.125*Convoquer+ 0.125*Aventurier+ 0.125*Homme bête+ 0.125*le plus fort+ 0.125*Commodité
0.151*Courageux+ 0.091*monstre+ 0.091*Beau+ 0.061*guerre+ 0.061*adorer
0.163*monstre+ 0.122*relation amicale+ 0.082*Aristocrate+ 0.082*Parvenu+ 0.082*le plus fort
0.260*esprit+ 0.054*Aristocrate+ 0.054*la comédie+ 0.054*sérieux+ 0.054*Nation/Gens
0.143*Aventurier+ 0.096*bataille+ 0.096*sérieux+ 0.096*Affaires domestiques+ 0.049*Parvenu
0.189*la comédie+ 0.143*Malentendu+ 0.096*VRMMORPG + 0.096*la comédie+ 0.049*Lycéen
0.147*Dragon+ 0.118*le plus fort+ 0.060*Elfe+ 0.060*bataille+ 0.060*guerre
0.173*esclave+ 0.088*Voyage+ 0.088*la magie+ 0.045*croissance+ 0.045*monstre
0.173*Affaires domestiques+ 0.088*Courageux+ 0.088*Voyage+ 0.045*le plus fort+ 0.045*esclave
0.130*sérieux+ 0.088*bataille+ 0.088*Lycéen+ 0.088*Senki+ 0.088*Transfert dans un autre monde
0.143*compétence+ 0.107*Modèle+ 0.072*guerre+ 0.072*Parvenu+ 0.072*la magie
0.206*guerre+ 0.070*Affaires domestiques+ 0.070*moyen Âge+ 0.070*Convoquer+ 0.070*Nation/Gens
0.130*esclave+ 0.130*guilde+ 0.088*Aristocrate+ 0.088*Convoquer+ 0.045*guerre

Après tout, c'était juste de la fantaisie ...

Mais si vous regardez bien, c'est un peu comme "Serious, Battle, High School Student, Senki, Another World Transfer", "SF, Trip, VRMMO, Narurokon Grand Prize, Rise", "War, Domestic Affairs, Medieval, Summon, Nation / Ethnicity" Semble être un genre différent, donc c'est mieux que quand j'ai fait le processus par défaut dictionary.filter_extremes ().

Recommended Posts

Analysez le modèle thématique pour devenir romancier avec GensimPy3
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
Prenez des captures d'écran LCD avec Python-LEGO Mindstorms
Visualisez le vocabulaire caractéristique d'un document avec D3.js
Calculer le produit des matrices avec une expression de caractère?
J'ai essayé de faire quelque chose comme un chatbot avec le modèle Seq2Seq de TensorFlow
Vérifiez l'effet du congé comme contre-mesure contre le nouveau virus corona avec le modèle SEIR
Un diagramme de réseau a été créé avec les données du COVID-19.
Mesurer l'importance des entités avec un outil de forêt aléatoire
Obtenez l'identifiant d'un GPU avec une faible utilisation de la mémoire
Obtenez UNIXTIME au début d'aujourd'hui avec une commande
Implémenter le modèle mathématique «modèle SIR» des maladies infectieuses avec Open Modelica
L'histoire du champ de modèle Django disparaissant de la classe
J'ai fait une fonction pour vérifier le modèle de DCGAN
Calibrer le modèle avec PyCaret
Nouvelle infection par le virus Corona: comprendre le rôle des stratégies de distance sociale avec un modèle simple
L'histoire de la création d'un bot de boîte à questions avec discord.py
J'ai essayé de prédire le nombre de personnes infectées au niveau national de la nouvelle corona avec un modèle mathématique
Traitez le contenu du fichier dans l'ordre avec un script shell
Une histoire coincée avec l'installation de la bibliothèque de machine learning JAX
Trouvez la valeur optimale de la fonction à l'aide d'un algorithme génétique (partie 2)
[Statistiques] Saisir l'image de la théorie de la limitation du pôle central avec un graphe
[Introduction à StyleGAN] J'ai joué avec "The Life of a Man" ♬
Si vous donnez une liste avec l'argument par défaut de la fonction ...
L'histoire de la création d'un pilote standard pour db avec python.
Compter la partie concaténée maximale d'un graphe aléatoire avec NetworkX
Obtenir l'URL du ticket JIRA créé par la bibliothèque jira-python
Évaluer les performances d'un modèle de régression simple à l'aide de la validation d'intersection LeaveOneOut
L'histoire de la création d'un module qui ignore le courrier avec python
Créez un programme de jugement de compatibilité avec le module aléatoire de python.
Simulation Python du modèle épidémique (modèle Kermack-McKendrick)
Analyse inverse du modèle d'apprentissage automatique
Créer un itérateur de modèle avec PySide
Validez le modèle d'entraînement avec Pylearn2
L'histoire de l'exportation d'un programme
Construction d'un environnement distribué avec la série Raspberry PI (Partie 1: Résumé de la disponibilité des clients sans disque par modèle)
Une histoire qui visualise le présent de Qiita avec Qiita API + Elasticsearch + Kibana
L'histoire d'un capteur de stationnement en 10 minutes avec le kit de démarrage GrovePi +
L'histoire de la création d'un robot LINE pour le petit-déjeuner d'une université de 100 yens avec Python
[Explication AtCoder] Contrôlez les problèmes A, B, C d'ABC182 avec Python!
Calculer l'itinéraire le plus court d'un graphe avec la méthode Dyxtra et Python
Mémorandum d'introduction du modèle de données EXODUS de la méthode des éléments finis (FEM)
Générez une liste contenant le nombre de jours du mois en cours.
Une série d'ingénieurs d'infrastructure amateurs touchant Django avec Docker (2): création d'un modèle
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
Apprenez les bases de la classification de documents par traitement du langage naturel, modèle de sujet
[NNabla] Comment ajouter une couche de quantification à la couche intermédiaire d'un modèle entraîné
Calculez la probabilité d'être une pièce de calmar avec le théorème de Bayes [python]
L'histoire de la création d'une caméra sonore avec Touch Designer et ReSpeaker
J'ai essayé d'analyser la négativité de Nono Morikubo. [Comparer avec Posipa]
J'ai fait GAN avec Keras, donc j'ai fait une vidéo du processus d'apprentissage.
Obtenez le salaire moyen d'un emploi avec des conditions spécifiées sur Indeed.com
J'ai fait une erreur en récupérant la hiérarchie avec MultiIndex of pandas
J'ai essayé de prédire le comportement du nouveau virus corona avec le modèle SEIR.
[Explication AtCoder] Contrôle ABC184 Problèmes A, B, C avec Python!
[Python & SQLite] J'ai analysé la valeur attendue d'une course avec des chevaux dans la fourchette 1x win ①