[PYTHON] J'ai fait un graphique radar des émotions du travail d'Aozora Bunko

Aperçu

introduction

Ceci est l'article du 14ème jour du "Calendrier de l'Avent Fujitsu Cloud Technologies 2019". Hier était @ 213 L'histoire de l'obstacle survenu cette année ..

M. 213 a-t-il survécu le vendredi 13? Je suis curieux.

Sujet principal

Les gens veulent soudainement lire un livre, mais selon l'ambiance à ce moment-là, le contenu peut être clair ou sombre et la tendance du livre que vous voulez lire changera.

Cependant, je n'ai pas le temps de récupérer le synopsis et le contenu à la librairie **, et il est ouvert au public gratuitement sur le net Aozora Bunko Il n'y a pas de synopsis dans /), donc vous ne pouvez pas comprendre de quel genre de travail il s'agit à moins de le lire.

Ensuite, faisons en sorte que vous puissiez comprendre le contenu du livre en un coup d'œil ** sans vérifier le contenu.

Ce que j'ai fait

Pour que l'humanité comprenne le contenu en un coup d'œil, il est encore nécessaire de ** illustrer le contenu du livre **. Par conséquent, j'ai analysé le contenu du livre et en ai fait ** une carte radar **. Il semble que la «disqualification humaine» a beaucoup de composants ** aversion **, et «pas de vent» a beaucoup de composants ** joie **.

ningenshikkaku.png1.pngkokor.pngningenisu.png

la mise en oeuvre

Objectif

Compte tenu de l'URL de travail d'Aozora Bunko, un graphique radar centré sur les émotions sera produit.

Environnement de travail

Google colaboratory

Vrai travail

Pouvoir illustrer en japonais

Par défaut, les étiquettes japonaises utilisant matplotlib sur google colabratory seront déformées. Par conséquent, j'ai téléchargé la police et supprimé le cache afin de pouvoir tracer le japonais. Après la suppression, il sera reflété une fois que l'exécution est redémarrée.

!apt-get -y install fonts-ipafont-gothic
!rm /root/.cache/matplotlib/fontlist-v310.json
!rm /root/.cache/matplotlib/fontList.json
#Redémarrez le runtime

Télécharger le dictionnaire des émotions

Ensuite, j'ai téléchargé le dictionnaire des émotions utilisé cette fois pour extraire les expressions émotionnelles. Ceci est publié dans ML-Ask, [The 3-Clause BSD License]( C'est un dictionnaire open source selon https://opensource.org/licenses/BSD-3-Clause).

!wget http://arakilab.media.eng.hokudai.ac.jp/~ptaszynski/ccount/click.php?id=3 -O emotions.zip
!unzip emotions.zip

Après avoir téléchargé le fichier zip et décompressé, vous verrez une sortie similaire à ce qui suit. Si vous cochez ici, vous pouvez voir que plusieurs fichiers texte sont enregistrés dans le répertoire ʻemotions` sous le répertoire de travail. Chacun correspond à ** "tristesse", "honte", "colère", "aversion", "peur", "surprise", "bien", "昂", "pas cher", "joie" ** Dans le fichier, les mots et les phrases qui correspondent à ce sentiment sont enregistrés.

Archive:  emotions.zip
   creating: emotions/
  inflating: emotions/aware_uncoded.txt  
  inflating: emotions/haji_uncoded.txt  
  inflating: emotions/ikari_uncoded.txt  
  inflating: emotions/iya_uncoded.txt  
  inflating: emotions/kowa_uncoded.txt  
  inflating: emotions/odoroki_uncoded.txt  
  inflating: emotions/suki_uncoded.txt  
  inflating: emotions/takaburi_uncoded.txt  
  inflating: emotions/yasu_uncoded.txt  
  inflating: emotions/yorokobi_uncoded.txt  

Quand j'ai vérifié le contenu de ʻaware_uncoded.txt`, j'ai trouvé que chaque ligne contenait un mot classé comme "chagrin".

!head emotions/aware_uncoded.txt
Ma poitrine se déchire
Aspirer
Gratté en larmes
Visage nuageux
Viens avec moi
Cri
Pleurs
Pleurs
Pleurer et pleurer
Lever

Lire les données du dictionnaire des émotions

Maintenant que nous avons confirmé que le dictionnaire a été téléchargé avec succès, chargez les données afin qu'elles puissent être gérées sur python. Pour cela, nous avons défini les fonctions suivantes. Convertit les mots et les phrases séparés pour chaque émotion en un seul ** format dict ** et le renvoie.

def get_emotional_words():
  emotions = ["aware", "haji", "ikari", "iya", "kowa", "odoroki", "suki", "takaburi", "yasu", "yorokobi"]
  emotional_words = {}
  for emotion in emotions:
    emotional_words[emotion] = []
    with open("emotions/" + emotion + "_uncoded.txt", "r") as f:
        for line in f:
          line = line.replace('\n','')
          emotional_words[emotion].append(line)
  return emotional_words

Acquisition des données de travail d'Aozora Bunko

Maintenant, ensuite, je vais extraire les données de travail dont je veux vérifier le contenu. Les données d'Aozora Bunko sont également publiées sur git, mais cette fois, j'ai obtenu les données de html. Profitant de mon expérience dans Mon article il y a environ 2 ans, j'essaie d'obtenir un pré-traitement pour obtenir les données.

def get_txt_from_aozorabunko(url):
  html = urllib.request.urlopen(url=url)
  soup = BeautifulSoup(html, "html.parser")
  #Récupérez le texte →<div class="main_text">~ Corps ~</div>
  sentences = soup.find("div","main_text")
  #Extraire uniquement la partie du personnage
  sentences = sentences.get_text().replace("\r", "").replace("\n", "").replace("\u3000", "")
  #Supprimez les caractères et les crochets entre crochets pleine largeur (car ruby existe sous forme de caractères entre crochets)
  sentences = re.sub("(.*?)", "", sentences) 
  return sentences

Analyse des émotions

Maintenant que nous pouvons lire le dictionnaire et obtenir les données textuelles de l'œuvre, créons une fonction d'analyse des émotions. Cette fois, nous avons adopté la méthode ** basée sur le dictionnaire ** et effectué une analyse des émotions en utilisant une méthode relativement simple. Plus précisément, il compte le nombre de mots contenus dans le dictionnaire des émotions dans les données textuelles de l'œuvre. Voici le code actuel.

def count_emotional_words(sentences, emotional_words):
  count_emotions = [0] * len(emotional_words.keys())
  for idx, emotion in enumerate(emotional_words.keys()):
    for word in emotional_words[emotion]:
      count_emotions[idx] += sentences.count(word)
  return count_emotions

Créer une carte radar

Créez un code pour créer un graphique radar de la fréquence d'apparition du dernier mot d'expression émotionnelle acquis. Cet article a été très utile pour créer le code. Merci beaucoup. Entrez la liste des noms d'émotions dans labels et la fréquence des mots d'expression d'émotion reçus par la fonction count_emotional_words dans values.

def plot_polar(labels, values, title):
  jp_font = {'fontname':'IPAGothic'}
  angles = np.linspace(0, 2 * np.pi, len(labels) + 1, endpoint=True)
  values = np.concatenate((values, [values[0]]))  #Faites-en un polygone fermé
  fig = plt.figure()
  ax = fig.add_subplot(111, polar=True)
  ax.plot(angles, values, 'o-')  #Cadre extérieur
  ax.fill(angles, values, alpha=0.25)  #remplir
  ax.set_thetagrids(angles[:-1] * 180 / np.pi, labels, fontsize=15, **jp_font)  #Étiquette d'axe
  ax.set_rlim(0 ,max(values))
  ax.set_title("「" + title + "」", fontsize=15, **jp_font)

Courir

Enfin, exécutez-le avec la fonction main. Si l'URL d'Aozora Bunko et le titre de l'œuvre sont donnés à cette fonction principale, une carte radar comme celle du début sera sortie.

def main(url, title):
  sentences = get_txt_from_aozorabunko(url)
  emotional_words = get_emotional_words()
  count_emotions = count_emotional_words(sentences, emotional_words)
  emotional_kanji = ["Chagrin", "la honte", "Fâché", "Ne pas aimer", "Effrayant", "Surprise", "Bien", "昂", "Ahn", "Joie"]
  labels = list(emotional_kanji)
  values = count_emotions
  plot_polar(labels, values, title)

Exemple d'exécution

En fait, j'ai essayé de saisir "Disqualification humaine" d'Osamu Osamu.

#URL de travail d'Aozora Bunko
ningen_shikkaku = "https://www.aozora.gr.jp/cards/000035/files/301_14912.html"
main(ningen_shikkaku,"Disqualification humaine")

ningenshikkaku.png

** J'ai pu faire un graphique radar de la tendance émotionnelle du travail en toute sécurité! ** **

résultat

Tendances pour chaque œuvre

Vérifions à nouveau l'exemple de sortie au début. Si vous vous concentrez sur la «disqualification humaine», vous avez l'impression que ** «Kazenai» est une œuvre assez brillante **. D'un autre côté, l'atmosphère générale de "Kokoro" est similaire à celle de "Disqualification humaine", mais ** elle peut avoir une composante d'amour plus forte car elle a une grande composante favorable ** (qui parlent toutes deux d'amour de couleur, mais " Je pense que «cœur» était une expression plus directe des émotions). D'un autre côté, on peut déduire de la ** vision étrange du monde que "Human Chair" de Ranpo Edogawa a tendance à avoir une composante plus effrayante que d'autres œuvres **. ningenshikkaku.png1.pngkokor.pngningenisu.png

À la fin

Impressions

** Amusant de voir les graphiques radar de diverses œuvres ** (Running Meros a une quantité étonnamment grande de tristesse)

** J'ai pu analyser avec une méthode simple basée sur un dictionnaire **

** Il existe peu de dictionnaires d'émotions japonais ** (celui que j'ai utilisé cette fois et SNOW)

Je voulais aussi faire ça

** Toolisation Web ** (C'était cool de pouvoir l'exécuter à partir d'un navigateur)

** Réorganisation du dictionnaire ** (Puisqu'il existe quelques 10 types d'expressions émotionnelles, faites une collection d'environ 5 types)

** Visualisons la différence entre le début et la fin de l'histoire ** (Le développement de l'histoire semble être visible!)

Le prochain calendrier de l'Avent est

Demain, M. yoshitsugumiyazaki a déclaré: "Il est fort possible de résumer les préoccupations liées à l'IA". C'est toujours du matériel IA. J'ai hâte de savoir quel type de contenu sera mis en place!

Recommended Posts

J'ai fait un graphique radar des émotions du travail d'Aozora Bunko
J'ai créé un installateur Ansible
J'ai créé un serveur Xubuntu.
J'ai fait un peintre discriminateur Anpanman
J'ai fait un kit de démarrage angulaire
J'ai créé une application d'analyse de fréquence en ligne
J'ai créé un module alternatif pour les japandas.
Quelles sont les caractéristiques des actrices audiovisuelles? J'ai deviné d'après le titre de l'oeuvre! (^ _ ^) / ~~
J'ai créé une commande appdo pour exécuter des commandes dans le contexte de l'application
Avec LINEBot, j'ai fait une application qui m'informe de "l'heure du bus"