[PYTHON] J'ai essayé d'analyser les émotions de tout le roman "Weather Child" ☔️

752B7BFA-4985-442D-904C-BEB091269C6C.gif

1. Un bref aperçu

Dans cet article, je vais vous expliquer comment traiter le texte du roman ** "Weather Child" ** </ font> en langage naturel et analyser les émotions!

En général, ** l'analyse des émotions ** fait référence à la découverte et à la quantification des ** «émotions» ** contenues dans une phrase et à l'appréciation de l'opinion de la phrase. C'est un domaine qui attire actuellement l'attention car il permet aux utilisateurs de classer mécaniquement leurs opinions sur leurs produits et services.

D'autre part "N'est-il pas possible d'utiliser l'analyse des émotions en plus des critiques et du bouche-à-oreille?" Dans cet article, j'ai décidé de relever le défi de l'analyse émotionnelle basée sur ** "novel" ** </ font>, ce qui est rarement fait dans la rue.

Le but de cet article est d'analyser les sentiments du roman **, "Est-il possible de déduire le développement approximatif de l'histoire et le caractère des personnages? **".

Par exemple, dans une histoire ・ Si les hauts et les bas des valeurs émotionnelles sont intenses, c'est une évolution très dramatique. ・ Si vous trouvez un tournant entre positif </ font> et négatif </ font> en fonction de votre valeur émotionnelle, vous pouvez découvrir objectivement l'origine et la transition de l'histoire. ça peut Etc.

Et le sujet que j'ai choisi cette fois est Weather Child </ font>! C'est un grand succès suite au travail précédent ** "Votre nom est." **, et beaucoup de gens ont peut-être vu le film.

image.png [Novel Weather Child (Kakugawa Bunko) -amazon](https://www.amazon.co.jp/%E5%B0%8F%E8%AA%AC-%E5%A4%A9%E6%B0%97 % E3% 81% AE% E5% AD% 90-% E8% A7% 92% E5% B7% 9D% E6% 96% 87% E5% BA% AB-% E6% 96% B0% E6% B5% B7 -Cité de% E8% AA% A0 / dp / 4041026407)

Je pense que c'est encore nouveau dans ma mémoire ~~ (je l'ai oublié) ~~, donc si vous allez au théâtre, je pense que vous pouvez apprécier de le regarder tout en vous rappelant la scène du film.

Différence entre film et roman

――Dans le roman, l'histoire progresse tandis que les points de vue (à la première personne) des personnages sont modifiés. ―― Le point de vue principal est le point de vue du personnage principal, Hodaka, mais il y a aussi un chapitre sur Hina et Natsumi. «L'histoire est fondamentalement la même. L'explication est plus détaillée dans le roman.

Personnellement, je peux apprécier l'histoire sous un angle légèrement différent de celui du film.

2. Comment analyser les émotions

Cette fois, nous avons effectué l'analyse d'émotion la plus simple ** «Analyse négative positive» **. ** «Analyse positive / négative» ** signifie si le texte est une opinion positive </ font>, une opinion négative </ font>, ou C'est une méthode de classification qui juge si elle est neutre ou non à partir d'une série de mots. Tout d'abord, j'expliquerai le flux général de l'analyse des émotions avec un exemple simple. Tout d'abord, la phrase est analysée morphologiquement et décomposée en éléments morphologiques (mots) comme suit.

** "Hatto Natsumi lève la main énergiquement et Suga l'ignore. 』**

** ['Hai', 'et', 'Natsumi', 'san', 'ga', 'genki', 'to', 'hand', 'to', 'rise', ',', 'Suga' , 'San', 'is', 'it', 'to', 'ignore', 'do'] **

Ensuite, chaque mot est jugé comme positif </ font> ou négatif </ font>, et une valeur d'émotion est donnée à chacun.

** ['Hai', 0], ['et', 0], ['Natsumi', 0], ['san', 0], ['ga', 0], ['Genki', 1], ['To', 0], ['Hand', 0], ['Raise', 0], ['Raise', 0], [',', 0], ['Suga', 0], [' San ', 0], [' est ', 0], [' il ', 0], [' est ', 0], [' ignorer ', -1], [' faire ', 0] ​**

Dans cette phrase, pour remonter le moral et ignorer avec une polarité émotionnelle, Genki: +1 Ignorer: -1 La valeur émotionnelle de a été donnée.

Enfin, la valeur totale est calculée pour calculer la valeur d'émotion de la phrase. Dans le cas de la phrase ci-dessus, 1 + (-1) signifie que la valeur d'émotion est 0. De cette manière, la valeur émotionnelle est donnée pour chaque phrase.

Un dictionnaire des émotions est utilisé pour déterminer le degré de positif ou de négatif d'un mot. Un dictionnaire d'émotions est un dictionnaire dans lequel les mots positifs </ font> ou négatifs </ font> sont écrits à l'avance comme indiqué ci-dessous. est. Dans ce dictionnaire, si un mot contenant négatif (évaluation) vient, la valeur d'émotion est incrémentée de -1, et si une évaluation positive vient, elle est incrémentée de +1.

Les valeurs émotionnelles seront calculées à partir de ce dictionnaire. スクリーンショット 2019-12-15 16.43.49.png

De plus, comme indiqué ci-dessous, les spécifications permettent un jugement positif / négatif en utilisant plusieurs mots. [Coin de bouche + montée, +1] [Voix + pop, +1] [Énergique + pas, -1] [Inquiétude + somnolence, -1]

3. Créer un corpus

Commencez par créer le corpus original. Je l'ai fait moi-même comme ça avec l'aide d'un ami. ↓ スクリーンショット 2019-12-19 10.09.57.png ** * Pour des raisons de droits d'auteur, le corpus ne peut pas être publié, donc seule une partie de celui-ci sera introduite **

Un mot de M. S, ami et créateur du corpus Cette fois, j'ai entrepris la transcription avec l'intuition que «je ne sais pas, mais c'est définitivement un gars intéressant». Il faut une semaine entière pour copier et diviser plusieurs phrases en utilisant "Memo and Highlights" de Kindle. Pour être honnête, c'était très difficile. Vous pouvez copier et coller des pages et des conditions météorologiques tout en faisant glisser des phrases, mais si vous faites cela alors que vous êtes épuisé par le travail de copie et de collage, cela ressemble à un rallye ho. Au moment de la livraison, on m'a dit «Merci pour le corpus!», Mais maintenant j'avoue que j'ai été secrètement recherché sur Google parce que je ne comprenais pas le «corpus».

4. Préparez un dictionnaire des émotions

Comme mentionné ci-dessus, préparez-vous à une analyse émotionnelle. Cette fois, le laboratoire Inui-Okazaki de l'Université de Tohoku est ouvert au public ["Dictionnaire japonais de polarité d'évaluation"](http://www.cl.ecei.tohoku.ac.jp/index.php?Open%20Resources% 2FJapanese% 20Sentiment% 20Polarity% 20Dictionary) sera partiellement réorganisé et utilisé en fonction du contenu de l'enfant météo. J'ai créé mon propre ** "dictionnaire multi-mots" ** pour un jugement positif / négatif par plusieurs mots tels que [Mouth angle + up, +1] introduit plus tôt.

5. Donnez une valeur émotionnelle à chaque phrase

Importez le dictionnaire des émotions et affichez la valeur de l'émotion pour chaque phrase. Le code est donné à la fin de cet article, mais si vous souhaitez analyser rapidement les émotions japonaises, la bibliothèque ** "oseti" ** est très utile. Je l'ai également utilisé comme référence.

La bibliothèque d'analyse des sentiments oseti pour Python utilisant le dictionnaire de polarité d'évaluation japonais a été publiée

J'ai créé un script qui renvoie une valeur émotionnelle en tant que valeur de retour lors de la saisie de texte, et j'ai ajouté la valeur émotionnelle au bloc de données du corpus comme indiqué ci-dessous. スクリーンショット 2019-12-21 17.47.05.png

Description de la colonne

total_word_score_pair_list_abs1: Liste des éléments morphologiques avec des valeurs de polarité émotionnelle et leurs valeurs émotionnelles sum_positive_srore: somme des valeurs positives sum_pegative_srore: somme des valeurs négatives new_srore_sum: La somme des valeurs positives et négatives

6. Tracez le graphique de la transition des valeurs émotionnelles et comparez avec le contenu du roman

Représentons graphiquement la valeur émotionnelle à l'aide de seaborn de la bibliothèque de visualisation. Additionnez les valeurs émotionnelles de chaque page et examinez les ** transitions ** au fil du temps. L'axe des x est le nombre de pages et l'axe des y est la valeur de l'émotion. ** * Peut-être que des spoilers sont inclus à partir d'ici. Faites attention. </ font> **

Changements dans les valeurs émotionnelles page par page


import matplotlib.pyplot as plt
from statistics import mean, median
from matplotlib import pyplot as plt
import seaborn as sns; sns.set()
import re
%matplotlib inline

page_sum_df = df_tenki2.groupby("page_num").new_score_sum.sum().reset_index()
sns.lineplot(x="page_num", y="new_score_sum", data=page_sum_df)

Voici les résultats! スクリーンショット 2019-12-18 22.39.29.png

Les hauts et les bas des émotions sont assez intenses! Positive </ font> et Negative </ font> alternent. Que peut-on lire sur ce graphique

  • Le positif et le négatif apparaissent clairement sous forme d'ondulations sur chaque page --Il existe des pages avec des valeurs positives et négatives extrêmement élevées ――La valeur émotionnelle change (peut-être) en fonction de l'histoire et du développement. Cependant, les ondulations sont très fines dans le graphe, et les caractéristiques sont un peu difficiles à comprendre ...

Afin d'obtenir une fonctionnalité un peu plus grossière, remplaçons l'unité de page de l'axe x ** par l'unité de chapitre ** et additionnons-les.

Transition de la valeur émotionnelle dans les unités du chapitre


chapter_sum_df = df_tenki2.groupby("chapter_flag").new_score_sum.sum().reset_index()
sns.lineplot(x="chapter_flag", y="new_score_sum", data=chapter_sum_df)

スクリーンショット 2019-12-18 22.43.30.png

Que peut-on lire sur le graphique

  • Les fonctionnalités basées sur les chapitres peuvent être appréhendées plus globalement que sur les pages -Les valeurs émotionnelles sont ondulantes dans chaque chapitre, et dans le chapitre immédiatement après la chute de la valeur émotionnelle, la valeur émotionnelle a tendance à osciller positivement.
  • Il n'y a pas de chapitre avec des valeurs émotionnelles négatives dans les unités de chapitre.

Les hauts et les bas des émotions sont plus faciles à comprendre et à interpréter qu'auparavant!

Mais ... Regardez les valeurs de l'axe des y dans le graphique. Il existe peu de valeurs négatives </ font>. Les personnes qui ont vu des films et des romans se sont-elles senties mal à l'aise?

** "L'enfant du temps n'est-il pas un travail si paisible ...?" **

Alors allons plus loin et analysons. Ensuite, la valeur émotionnelle n'est pas la valeur totale, mais est divisée en valeur positive </ font> et valeur négative </ font> ** Dessinez un graphique.

chapter_sum_df = df_tenki2.groupby("chapter_flag").sum_positive_scores.sum().reset_index()
sns.lineplot(x="chapter_flag", y="sum_positive_scores", data=chapter_sum_df,color="red")
chapter_sum_df2 = df_tenki2.groupby("chapter_flag").sum_negative_scores.sum().reset_index()
sns.lineplot(x="chapter_flag", y="sum_negative_scores", data=chapter_sum_df2,color="blue")

Le graphique rouge est la transition de valeur positive </ font>, et le bleu est la transition de valeur négative </ font>. スクリーンショット 2019-12-19 11.23.04.png

Les caractéristiques positives et négatives sont désormais clairement visibles! Comme précédemment, lorsque la valeur positive et la valeur négative sont totalisées et exprimées dans un graphique, ** "Lorsque les valeurs positives et négatives affichaient des valeurs élevées, les valeurs étaient décalées et les caractéristiques étaient difficiles à voir." ** Il semble.

Maintenant, jetons un bref regard sur le contenu du roman.

En regardant le sentiment général, la plage de fluctuation des valeurs émotionnelles est grande au début et dans la seconde moitié de l'histoire. Dans le chapitre 2 et le chapitre 8 et plus tard, les valeurs positive </ font> et négative </ font> sont assez élevées. S'agit-il de la partie ** "ki" ** et de la partie ** "transition" ** en cas de transfert?

Ensuite, regardons l'ampleur de la valeur.

À partir de ce graphique, on peut voir que la valeur positive </ font> du chapitre 8 et du chapitre 10 est la plus grande et le chapitre 2 est la plus grande négative </ font>.

chapter8 Le chapitre 8 est une scène relativement paisible. Jouer ensemble dans le parc, consulter le petit frère de Hina ** "Nagi" ** ou acheter une bague pour que ** "Hawaka" ** avoue à ** "Hina" ** Je suis sur le point de partir. Pas étonnant que la valeur positive </ font> soit élevée.

chapter10 Le chapitre 10 est le point culminant de l'histoire. C'est une scène où ** "Sail Height" ** a du mal à aider ** "Hina" **. Non seulement valeur positive </ font> mais aussi valeur négative </ font> est élevée, donc la sensation de ** "hauteur de voile" ** est intense. Je peux imaginer que c'est le cas.

chapter2 Le chapitre 2 est la première scène de l'histoire. C'est une scène où "Hodaka" qui a quitté la maison vient à Tokyo et essaie de trouver un travail à temps partiel, mais est écrasé par les vagues de la ville, et se rend enfin au bureau de ** "Suga" ** et travaille. La valeur négative </ font> est-elle apparue là où vous étiez frotté par les vagues de la ville ou grondé par ** "Suga" **?

7. Comparez les valeurs émotionnelles de chaque personnage

À partir de là, comparons les valeurs émotionnelles de chaque personnage. Calculons la valeur émotionnelle moyenne par phrase du dialogue de chaque personnage.

Comment calculer la valeur moyenne

** Valeur émotionnelle totale du dialogue de chaque personnage / Nombre de dialogues de chaque personnage **

Cette fois, nous comparerons les quatre personnages principaux ** "Hodaka" **, ** "Hina" **, ** "Suga" **, ** "Natsumi" **.

df_tenki3=df_tenki2.groupby(['speaker_name'])['new_score_sum'].mean().reset_index()
df_tenki4 = df_tenki3.sort_values('new_score_sum', ascending=False)
df_tenki_person = df_tenki4[(df_tenki4["speaker_name"] == "suga") | (df_tenki4["speaker_name"] == "hodaka") | (df_tenki4["speaker_name"] == "natsumi") | (df_tenki4["speaker_name"] == "hina")]
sns.catplot(x="speaker_name", y="new_score_sum", data=df_tenki_person,height=6,kind="bar",palette="muted")

スクリーンショット 2019-12-21 15.56.58.png

Le positif et le négatif sont clairement séparés entre les hommes et les femmes.

Les femmes sont vraiment positives </ font>! Au contraire, les deux hommes sont assez négatifs </ font>.

Les deux affichent des valeurs très proches. En fait, même dans le roman, les personnages principaux Hotaka et Suga

** "Ces deux sont très similaires" **

Il y a une représentation qui est dite par l'environnement, mais vous pouvez voir qu'elle est similaire en termes de valeur émotionnelle.

Regardons également les valeurs positives </ font> et valeurs négatives </ font>.

df_tenki3=df_tenki2.groupby(['speaker_name'])['sum_positive_scores','sum_negative_scores'].mean().reset_index()
df_tenki4 = df_tenki3.sort_values('sum_positive_scores', ascending=False).reset_index()
df_tenki_person2 = df_tenki4[(df_tenki4["speaker_name"] == "suga") | (df_tenki4["speaker_name"] == "hodaka") | (df_tenki4["speaker_name"] == "natsumi") | (df_tenki4["speaker_name"] == "hina")]
sns.catplot(x="speaker_name", y="sum_positive_scores", data=df_tenki_person2,kind="bar",palette="muted")
sns.catplot(x="speaker_name", y="sum_negative_scores", data=df_tenki_person2,kind="bar",palette="muted")

スクリーンショット 2019-12-21 16.29.50.png

** "Hina" ** semble parler moins de mots négatifs </ font> que les trois. Quelle fille forte ... ** "Natsumi" ** a la valeur positive </ font> supérieure, mais la valeur négative </ font> est également raisonnablement élevée. ** "Natsumi" ** est généralement assez brillant, mais il existe divers mots négatifs </ font> tels que la haine de soi due à la difficulté à trouver un emploi et à se plaindre à Suga. J'ai l'impression que vous parlez. Et la valeur positive </ font> de ** "sail height" ** est assez faible. Certes, il n'y a pas beaucoup d'impression lumineuse ... Mais si le positif </ font> de ** "Hina" ** vous attire, ces deux peuvent être une bonne combinaison (?)

8. Y a-t-il une relation entre la météo et les valeurs émotionnelles?

Enfin, examinons la relation entre "weather" </ font> et les valeurs émotionnelles, qui sont les clés de cette histoire. La méthode consiste à calculer la valeur moyenne pour chaque scène météorologique comme dans le cas des personnages. Les types de temps sont classés dans les 6 catégories suivantes, à en juger par la description lors de la création du corpus. "Ensoleillé" "pluie" "pluie légère" "heavy_rain" "clair" "neige" Il existe trois types d'intensité de pluie, vous pouvez donc voir la relation entre l'intensité de la pluie et la valeur émotionnelle. D'ailleurs, en raison du cadre de l'histoire, la scène de l'histoire (Tokyo) est fondamentalement "pluie" sauf lorsque l'héroïne ** "Hina" ** souhaite une journée ensoleillée et quand ** quelque chose se passe **. C'est l'état de. Parce qu'il pleut tous les jours, tout le monde dans la ville veut qu'il s'éclaircisse.

hypothèse

** Par hypothèse, une scène ensoleillée sera positive </ font>, et plus la pluie sera lourde, le négatif </ font>. ?? ** **

Je m'y attendais. Voyons le résultat!

sns.catplot(x="weather_flag", y="new_score_sum", data=df_tenki2_edited,height=6,kind="bar",palette="muted")

スクリーンショット 2019-12-21 15.50.09.png

Après tout, le soleil est le plus positif </ font>! C'est prévisible! Cela ne semble pas avoir grand-chose à voir avec l'intensité de la pluie. Cependant, bien que "clear" soit très positif, "clear" n'a pas beaucoup changé vers positif </ font>. Pourquoi...? Comme mentionné ci-dessus, le temps ne se dégage que lorsque Hina souhaite une journée ensoleillée et que quelque chose se passe **, mais cette ** chose ** est ..... alors,

"Hina a disparu" </ font>

Avec la disparition de Hina, la ville qui pleuvait jusqu'à présent devient immédiatement claire. Cependant, le grand public, qui ne sait pas que ** "Hina" ** a été sacrifié, est docilement satisfait du temps ensoleillé. Cependant, seul le personnage principal ** "Sail Height" ** le sait et est très triste. Ce devrait être le meilleur temps de l'histoire, mais ici les sensations de ** "Sail height" ** vont dans la direction opposée au monde. Donc même s'il fait beau, ça ne devient pas très positif.

Enfin, en ce qui concerne la neige, c'est le plus négatif </ font>. Si vous avez regardé un film ici, vous en serez satisfait. C'est le point culminant, où ** "Sail Height" ** et ** "Hina" ** échappent à la police et s'échappent vers le Love Hotel. C'est une scène où il y a beaucoup d'expressions négatives </ font> parce que le monde et les hauteurs de voiles sont confondus par le temps extrêmement anormal qu'il neige même si nous sommes en août.

9. Conclusion

Ce que j'ai appris du roman par analyse émotionnelle ――Vous pouvez lire le développement approximatif de l'histoire et le tournant de la transition. ―― Vous pouvez juger approximativement le caractère du personnage à partir de la valeur positive / négative.

  • La transition des valeurs émotionnelles pour chaque série chronologique peut être facilement interprétée en les divisant en valeurs positives et négatives, chapitre par chapitre. Et cette fois, j'ai étudié la relation entre la météo et la valeur émotionnelle, qui est la plus facile à comprendre, mais il semble que des résultats intéressants sortiront si j'étudie également la relation avec d'autres facteurs. Si vous avez une idée du genre "Ce serait intéressant d'analyser ça!", J'apprécierais que vous commentiez.

10. Défis

Large gamme d'expression nouvelle

Bien sûr, j'étais préparé, mais il y avait un plus large éventail d'expressions dans le roman que ce à quoi je m'attendais, et il était difficile de donner des négatifs positifs mot par mot. Dans la dernière scène, ** "Sail height" ** crie "Le temps peut rester fou", mais c'est le positif </ font> le plus puissant de l'histoire. C'est une belle scène, mais si vous la prenez à la lettre, elle sera négative. Il y a une limite à donner simplement des valeurs émotionnelles en unités de mots, et c'est un endroit très difficile.

11. Code

#Fonction d'importation du dictionnaire de polarité des émotions
def _make_dict():
    
    import pandas as pd
    
    df_word_dict = pd.read_csv('./dict/edited_target_pair_list_word_out.csv')#nom
    df_wago_dict = pd.read_csv('./dict/edited_target_pair_list_wago_out.csv')#Mots
    df_one_gram_dict = pd.read_csv('./dict/one_gram_dict_out.csv')#Plusieurs mots

    word_dict = {}
    for pair_list in df_word_dict[['word','count']].values.tolist():
        if pair_list[1] !='0':
            word_dict[pair_list[0]] = pair_list[1]

    wago_dict = {}
    for pair_list in df_wago_dict[['word','count']].values.tolist():
        if pair_list[1] !='0':
            wago_dict[pair_list[0]] = pair_list[1]

    one_gram_dict = {}
    for pair_list in df_one_gram_dict[['word1','word2','score']].values.tolist():
        one_gram_dict[(str(pair_list[0]),str(pair_list[1]))] = pair_list[2]
    
    return word_dict,wago_dict,one_gram_dict

#Une fonction qui divise le texte phrase par phrase
def _split_per_sentence(text):
    import re
    re_delimiter = re.compile("[。,.!\?!?]")
    for sentence in re_delimiter.split(text):
        if sentence and not re_delimiter.match(sentence):
            yield sentence

def _sorted_second_list(polarities_and_lemmanum):
    from operator import itemgetter

    sorted_polarities_and_lemmanum=sorted(polarities_and_lemmanum, key=itemgetter(1))
    return [i[0] for i in sorted_polarities_and_lemmanum]

def _calc_sentiment_polarity(sentence):
        import MeCab
        word_dict,wago_dict,one_gram_dict = _make_dict()

        NEGATION = ('Absent', 'Zu', 'Nu','Hmm')
        tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
        tagger.parse('')  # for avoiding bug
        word_polarities = [] # word_Liste des valeurs émotionnelles correspondant à dict
        wago_polarities = [] # wago_Liste des valeurs émotionnelles correspondant à dict
        polarities_and_lemmanum = [] #Liste des valeurs émotionnelles finales et lemmanum
        lemmas = [] #Headword,Mots sous la forme listée dans le dictionnaire
        word_polarity_apeared = False
        wago_polarity_apeared = False
        
        word_nutoral_polarity_apeared = False
        wago_nutoral_polarity_apeared = False
        
        word_out_polarity_apeared = False
        wago_out_polarity_apeared = False
        
        word_polarity_word = '' #Provisoire pour la gestion des erreurs
        wago_polarity_word = '' #Provisoire pour la gestion des erreurs
        
        word_nutoral_word = ''
        wago_nutoral_word = ''
        
        word_out_polarity_word = ''
        wago_out_polarity_word = ''
        
        last_hinsi = ''
        last_word = ''
        
        node = tagger.parseToNode(sentence)
        word_score_pair_list = []
        lemma_num = 0#Pour noter l'ordre des mots
        lemma_dict = {}
        while node:
            if 'BOS/EOS' not in node.feature:
 
                surface = node.surface
                feature = node.feature.split(',')
                lemma = feature[6] if feature[6] != '*' else node.surface
                lemma_num += 1
                lemma_dict[lemma] = lemma_num
                #Traitement du lemme converti en mots au format répertorié dans le dictionnaire des mots divisés
                #Ce mot est un mot_Traitement lorsqu'il est en dict

                if word_polarity_apeared and (feature[0] not in ['Verbe auxiliaire','Particule'] and last_hinsi not in ['Verbe auxiliaire','Particule'] and last_word not in ['y a-t-il','Oru','Faire']) and last_word not in word_dict:
                    word_polarity_apeared = False  
                elif wago_polarity_apeared and (feature[0] not in ['Verbe auxiliaire','Particule'] and last_hinsi not in ['Verbe auxiliaire','Particule'] and last_word not in ['y a-t-il','Oru','Faire']) and last_word not in wago_dict:
                    wago_polarity_apeared = False
                elif word_nutoral_polarity_apeared and (feature[0] not in ['Verbe auxiliaire','Particule'] and last_hinsi not in ['Verbe auxiliaire','Particule'] and last_word not in ['y a-t-il','Oru','Faire']) and last_word not in word_dict:
                    word_nutoral_polarity_apeared = False
                elif wago_nutoral_polarity_apeared and (feature[0] not in ['Verbe auxiliaire','Particule'] and last_hinsi not in ['Verbe auxiliaire','Particule'] and last_word not in ['y a-t-il','Oru','Faire']) and last_word not in wago_dict:
                    wago_nutoral_polarity_apeared = False

                    
                try:
                    if word_dict[lemma] in ['p','n']:
                        polarity = 1 if word_dict[lemma] == 'p' else -1
                        word_polarities.append([polarity,lemma_dict[lemma]])
                        word_polarity_apeared = True
                        word_polarity_word = lemma
                    elif word_dict[lemma] == 'f':
                        word_polarities.append([0,lemma_dict[lemma]])
                        word_nutoral_polarity_apeared = True
                        word_nutoral_word = lemma
                        polarity = 0
                        #word_Puisque 0 est effacé à l'avance avec dict, sinon le traitement est inutile, mais laissez-le en considération de la lisibilité.
                    else:
                        polarity = 0
                #word_Quand il n'y a pas de mot dans dict
                except:
                    #wago_Quand il y a un mot dans dict
                    try:
                        if wago_dict[lemma] in ['Positif (expérience)','Négatif (expérience)','Positif (évaluation)','Négatif (évaluation)']:
                            polarity = 1 if wago_dict[lemma] in ['Positif (expérience)','Positif (évaluation)'] else -1
#                             print(polarity)
                            wago_polarities.append([polarity,lemma_dict[lemma]])
                            wago_polarity_apeared = True
                            wago_polarity_word = lemma
                        elif wago_dict[lemma] == 'neutre':
                            wago_polarities.append([0,lemma_dict[lemma]])
                            wago_nutoral_polarity_apeared = True
                            wago_nutoral_word = lemma
                            polarity = 0
                        else:
                            polarity = 0
                     #word_dict aussi wago_Traitement lorsqu'il n'y a pas de mot dans dict
                    except:  
                        if word_polarity_apeared and surface in NEGATION and wago_nutoral_polarity_apeared is False:

                            if last_hinsi in ['nom','Particule','Verbe auxiliaire','verbe','adjectif']:

                                word_polarities[-1][0] *= -1
                                try:
                                    reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([word_polarity_word,1])+1)
                                except:
                                    reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([word_polarity_word,-1])+1)
                                finally:

                                    word_score_pair_list[reverse_num]=[word_polarity_word+'+'+lemma,word_polarities[-1][0]]
                                    word_polarity_apeared = False
                                    word_polarity_word = ''
                                    polarity = 0
                            else:
                                polarity = 0
                        #"Veuillez corriger" "Veuillez améliorer"-Traitement à 1
                        elif lemma in ['Donnez-moi','vouloir','Souhait']:
                            
                            try:
                                if word_polarity_word or word_nutoral_word !='':
                                    last_polarities_word = [i for i in [word_polarity_word,word_nutoral_word] if i !=''][0]
                                    try:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,word_polarities[-1][0]])+1)
                                    except:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,word_polarities[-1][0]])+1)
                                    finally:
                                        word_score_pair_list[reverse_num]=[last_polarities_word+'+'+surface,-1]#Valeur émotionnelle-Accorder 1
                                        word_polarity_apeared = False
                                        word_polarity_word = ''
                                        word_polarities[-1][0] = -1
                                        polarity = 0
                                    
                                elif wago_polarity_word or wago_nutoral_word !='':
                                    last_polarities_word = [i for i in [wago_polarity_word,wago_nutoral_word] if i !=''][0]
                                    try:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,wago_polarities[-1][0]])+1)
                                    except:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,wago_polarities[-1][0]])+1)
                                    finally:
                                        word_score_pair_list[reverse_num]=[last_polarities_word+'+'+surface,-1]#Valeur émotionnelle-Accorder 1
                                        wago_polarity_apeared = False
                                        wago_polarity_word = ''
                                        wago_polarities[-1][0] = -1
                                        polarity = 0
                            except:
                                polarity = 0
                                #Quand il y a un "ka" à la fin de la phrase-Traitement à 1
                        elif last_hinsi in ['Verbe auxiliaire','Particule'] and lemma == 'Ou':
                            
                            try:
                                if word_polarity_word or word_nutoral_word !='':
                                    last_polarities_word = [i for i in [word_polarity_word,word_nutoral_word] if i !=''][0]
                                    try:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,word_polarities[-1][0]])+1)
                                    except:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,word_polarities[-1][0]])+1)
                                    finally:
                                        word_score_pair_list[reverse_num]=[last_polarities_word+'+'+surface,-1]#Valeur émotionnelle-Accorder 1
                                        word_polarity_apeared = False
                                        word_polarity_word = ''
                                        word_polarities[-1][0] = -1
                                        polarity = 0
                                    
                                elif wago_polarity_word or wago_nutoral_word !='':
                                    last_polarities_word = [i for i in [wago_polarity_word,wago_nutoral_word] if i !=''][0]
                                    try:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,wago_polarities[-1][0]])+1)
                                    except:
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([last_polarities_word,wago_polarities[-1][0]])+1)
                                    finally:
                                        word_score_pair_list[reverse_num]=[last_polarities_word+'+'+surface,-1]#Valeur émotionnelle-Accorder 1
                                        wago_polarity_apeared = False
                                        wago_polarity_word = ''
                                        wago_polarities[-1][0] = -1
                                        polarity = 0
                            except:
                                polarity = 0
                            
                        elif word_nutoral_polarity_apeared:

                            if last_hinsi in ['nom','Particule','Verbe auxiliaire','verbe'] and lemma in NEGATION:
                                lemma_type = 'le déni'
                                try:
                                    word_polarities[-1][0] += one_gram_dict[(word_nutoral_word,lemma_type)]
                                    reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([word_nutoral_word,0])+1)
                                    word_score_pair_list[reverse_num]=[word_nutoral_word+'+'+lemma,one_gram_dict[(word_nutoral_word,lemma)]]
                                    word_nutoral_polarity_apeared = False
                                    word_nutoral_word = ''
                                except:
                                    polarity = 0
                            elif last_hinsi in ['nom','Particule','Verbe auxiliaire','verbe'] and lemma not in NEGATION:
                                try:
                                    word_polarities[-1][0] += one_gram_dict[(word_nutoral_word,lemma)]
                                    reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([word_nutoral_word,0])+1)
                                    word_score_pair_list[reverse_num]=[word_nutoral_word+'+'+lemma,one_gram_dict[(word_nutoral_word,lemma)]]
                                    word_nutoral_polarity_apeared = False
                                    word_nutoral_word = ''
                                except:
                                    polarity = 0
                    #Ce mot est un mot_Que faire si ce n'était pas dans le dict
                        else:            
                        #Le mot est,Absent', 'Zu', 'Nu'Si tel est le cas, inversez la polarité du mot précédent
                            if wago_polarity_apeared and surface in NEGATION and wago_nutoral_polarity_apeared is False\
                            and word_polarity_apeared is False and word_nutoral_polarity_apeared is False:

                                if last_hinsi in ['nom','adjectif','Verbe auxiliaire']:

                                    wago_polarities[-1][0] *= -1
                                    reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([wago_polarity_word,wago_polarities[-1][0]*(-1)])+1)
                                    word_score_pair_list[reverse_num]=[wago_polarity_word+'+'+lemma,wago_polarities[-1][0]]
                                    wago_polarity_apeared = False
                                    word_polarity_word = ''
                                    polarity = 0
                                else:
                                    polarity = 0
                            
                            elif wago_nutoral_polarity_apeared:
                                #Traitement neutre + refus
                                if last_hinsi in ['verbe','Particule','助verbe'] and lemma in NEGATION:
                                    lemma_type = 'le déni'   
                                    try:
                                        lemma_type = 'le déni'
                                        wago_polarities[-1][0] += one_gram_dict[(wago_nutoral_word,lemma_type)]
                                        #Traitement pour tracer la liste à l'envers
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([wago_nutoral_word,0])+1)
                                        word_score_pair_list[reverse_num]=[wago_nutoral_word+'+'+lemma,one_gram_dict[(wago_nutoral_word,lemma_type)]]
                                        wago_nutoral_polarity_apeared = False
                                        wago_nutoral_word = ''
                                    except:
                                        polarity = 0
                                #Traitement autre que neutre + refus
                                elif last_hinsi in ['nom','verbe','adjectif','Particule','助verbe'] :
                                    try:
                                        wago_polarities[-1][0] += one_gram_dict[(wago_nutoral_word,lemma)]
                                        #Traitement pour tracer la liste à l'envers
                                        reverse_num = -1*([i for i in reversed(word_score_pair_list)].index([wago_nutoral_word,0])+1)
                                        word_score_pair_list[reverse_num]=[wago_nutoral_word+'+'+lemma,one_gram_dict[(wago_nutoral_word,lemma)]]
                                        wago_nutoral_polarity_apeared = False
                                        wago_nutoral_word = ''
                                    except:
                                        polarity = 0
                                else:
                                    polarity = 0
                            else:
                                polarity = 0

          
                word_score_pair = [lemma,polarity]
                word_score_pair_list.append(word_score_pair)

                last_hinsi = node.feature.split(',')[0]
                last_word = lemma
            node = node.next
        if word_polarities:
            polarities_and_lemmanum.extend(word_polarities)
        if wago_polarities:
            polarities_and_lemmanum.extend(wago_polarities)
        #lemma_Tri croissant par nombre
        try:
            polarities = _sorted_second_list(polarities_and_lemmanum)
        #Utilisez uniquement des valeurs de polarité non nulles. Si 0 reste, une erreur se produira dans le traitement suivant.
            polarities = [i for i in polarities if i !=0]
        except:
            polarities = []
        
        try:
            if sum(polarities) / len(polarities) ==0:
                score = float(polarities[-1])
#                 print('=================================================')
                print(sentence+'→ → La priorité est donnée à la valeur émotionnelle à la fin de la phrase')
#                 print('=================================================')
                
            else:
                score = sum(polarities) / len(polarities) 
        except:
                score = 0
        
        if not polarities:
            return 0,0,0,word_score_pair_list
        return score,sum(i for i in polarities if i > 0),sum(i for i in polarities if i < 0),word_score_pair_list
    
def _analyze(text):
        scores,total_word_score_pair_list,positive_word_cnt_list,negative_word_cnt_list = [],[],[],[]
        
        for sentence in _split_per_sentence(text):
            #Remplacer les phrases pour l'analyse des émotions Exemple: Non → Non
            replaced_sentence = _emotion_replace_text(sentence)
            score,positive_word_cnt,negative_word_cnt,word_score_pair_list = _calc_sentiment_polarity(replaced_sentence)
            scores.append(score)
            positive_word_cnt_list.append(positive_word_cnt)
            negative_word_cnt_list.append(negative_word_cnt)
            total_word_score_pair_list.append(word_score_pair_list)

        return scores,positive_word_cnt_list,negative_word_cnt_list,total_word_score_pair_list

def _flatten_abs1(x):
    #Une fonction qui aplatit une double liste et en fait une liste de paires uniquement avec des valeurs émotionnelles
    return [e for inner_list in x for e in inner_list if e[1] !=0]

def score_sum_get(x):
    #_flatten_Une fonction qui résume les valeurs émotionnelles obtenues par abs1
    emo_list=[]
    for inner_list in x:
        for e in inner_list:
            if e[1] !=0:
                emo_list.append(e[1])
    return sum(emo_list)


from datetime import datetime as dt
from datetime import date


#Lecture des données d'entraînement
import pandas as pd
path='./data/tenkinoko.csv'
df_tenki = pd.read_csv(path,encoding="SHIFT-JIS")
df_tenki["chapter_flag"] = df_tenki.chapter.apply(chapter_flag)

add_col_name=['scores','positive_word_cnt_list','negative_word_cnt_list','total_word_score_pair_list']
for i in range(len(add_col_name)):
    col_name=add_col_name[i]
    df_tenki2[col_name]=df_tenki2['text'].apply(lambda x:_analyze(x)[i])

df_tenki2['score_sum']=df_tenki2['scores'].apply(lambda x:sum(x))
#Comptez le nombre de positifs par mot
df_tenki2['sum_positive_scores']=df_tenki2['positive_word_cnt_list'].apply(lambda x:sum(x))
#Comptez le nombre de négatifs par mot
df_tenki2['sum_negative_scores']=df_tenki2['negative_word_cnt_list'].apply(lambda x:sum(x))
#Avec des mots polaires émotionnels[morphème,Valeur émotionnelle]Traitement pour ne faire que des paires de
df_tenki2['total_word_score_pair_list_abs1']=df_tenki2['total_word_score_pair_list'].apply(lambda x:_flatten_abs1(x))

#Calculez la valeur émotionnelle totale
df_tenki2['new_score_sum']=df_tenki2['total_word_score_pair_list'].apply(lambda x:score_sum_get(x))

Recommended Posts