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.
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.
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.
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.
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 ().