[PYTHON] Ich habe versucht, die Emotionen des gesamten Romans "Wetterkind" zu analysieren

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

1. Ein kurzer Überblick

In diesem Artikel werde ich erklären, wie man den Text des Romans ** "Weather Child" ** </ font> in natürlicher Sprache verarbeitet und Emotionen analysiert!

Im Allgemeinen bezieht sich ** Emotionsanalyse ** auf das Entdecken und Quantifizieren von ** "Emotionen" **, die in einem Satz enthalten sind, und das Beurteilen der Meinung des Satzes. Dies ist ein Bereich, der derzeit Aufmerksamkeit erregt, da Benutzer ihre Meinungen zu ihren Produkten und Dienstleistungen mechanisch klassifizieren können.

Auf der anderen Seite "Ist es nicht möglich, zusätzlich zu Bewertungen und Mundpropaganda eine Emotionsanalyse zu verwenden?" In diesem Artikel habe ich mich daher entschlossen, die Emotionsanalyse auf der Grundlage von ** "Novel" ** </ font> in Frage zu stellen, was auf der Straße selten durchgeführt wird.

Der Zweck dieses Artikels ist es, die Gefühle des Romans zu analysieren. ** "Ist es möglich, auf die grobe Entwicklung der Geschichte und den Charakter der Charaktere zu schließen? **".

Zum Beispiel in einer Geschichte ・ Wenn das Auf und Ab emotionaler Werte intensiv ist, ist dies eine sehr dramatische Entwicklung. ・ Wenn Sie basierend auf Ihrem emotionalen Wert einen Wendepunkt von positiv </ font> zu negativ </ font> finden, können Sie den Ursprung und den Übergang der Geschichte objektiv entdecken. es kann Und so weiter.

Und das Thema, das ich dieses Mal gewählt habe, ist Wetterkind </ font>! Es ist ein großer Erfolg nach der vorherigen Arbeit ** "Ihr Name ist." **, und viele Leute haben den Film vielleicht gesehen.

image.png [Neuartiges Wetterkind (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 -Zitiert aus% E8% AA% A0 / dp / 4041026407)

Ich denke, es ist noch neu in meiner Erinnerung ~~ (ich habe es vergessen) ~~. Wenn Sie also ins Theater gehen, können Sie es genießen, wenn Sie sich an die Filmszene erinnern.

Unterschied zwischen Film und Roman

――In dem Roman geht die Geschichte weiter, während die Sichtweisen (erste Person) der Charaktere geändert werden. ――Der Hauptstandpunkt ist der Standpunkt der Hauptfigur Hodaka, aber es gibt auch ein Kapitel über Hina und Natsumi. ――Die Geschichte ist im Grunde die gleiche. Die Erklärung ist im Roman ausführlicher.

Persönlich kann ich die Geschichte aus einer etwas anderen Perspektive als den Film genießen.

2. Wie man Emotionen analysiert

Dieses Mal haben wir die einfachste Emotionsanalyse durchgeführt ** "Positive Negative Analysis" **. ** "Positive / Negative Analyse" ** bedeutet, ob der Text eine positive </ font> Meinung, eine negative </ font> Meinung ist oder Es ist eine Klassifizierungsmethode, die anhand einer Reihe von Wörtern beurteilt, ob sie neutral ist oder nicht. Zunächst werde ich den allgemeinen Ablauf der Emotionsanalyse anhand eines einfachen Beispiels erläutern. Zunächst wird der Satz morphologisch analysiert und wie folgt in morphologische Elemente (Wörter) zerlegt.

** "Hatto Natsumi hebt energisch ihre Hand und Suga ignoriert sie. 』**

** ['Hai', 'und', 'Natsumi', 'san', 'ga', 'genki', 'zu', 'hand', 'zu', 'erhöhen', ',', 'Suga' , 'San', 'ist', 'es', 'zu', 'ignorieren', 'tun'] **

Dann wird für jedes Wort beurteilt, ob es positiv </ font> oder negativ </ font> ist, und jedem wird ein Emotionswert gegeben.

** ['Hai', 0], ['und', 0], ['Natsumi', 0], ['san', 0], ['ga', 0], ['Genki', 1], ['To', 0], ['Hand', 0], ['Raise', 0], ['Raise', 0], [',', 0], ['Suga', 0], [' San ', 0], [' ist ', 0], [' es ', 0], [' ist ', 0], [' ignorieren ', -1], [' tun ', 0] ​**

In diesem Satz, energisch und mit emotionaler Polarität zu vernachlässigen, Genki: +1 Ignorieren: -1 Der emotionale Wert von wurde gegeben.

Schließlich wird der Gesamtwert berechnet, um den Satzemotionswert zu berechnen. Im Fall des obigen Satzes bedeutet 1 + (-1), dass der Emotionswert 0 ist. Auf diese Weise wird der emotionale Wert für jeden Satz angegeben.

Ein Emotionswörterbuch wird verwendet, um den Grad des Positiven oder Negativen eines Wortes zu bestimmen. Ein Emotionswörterbuch ist ein Wörterbuch, in dem die Wörter positiv </ font> oder negativ </ font> wie unten gezeigt im Voraus geschrieben werden. ist. Wenn in diesem Wörterbuch ein Wort mit Negativ (Bewertung) kommt, wird der Emotionswert um -1 erhöht, und wenn ein Positiv (Bewertung) kommt, wird es um +1 erhöht.

Emotionale Werte werden basierend auf diesem Wörterbuch berechnet. スクリーンショット 2019-12-15 16.43.49.png

Darüber hinaus ermöglichen die Spezifikationen, wie unten gezeigt, eine positive / negative Beurteilung unter Verwendung mehrerer Wörter. [Mundecke + Aufstieg, +1] [Stimme + Pop, +1] [Energetisch + nicht, -1] [Besorgt + schläfrig, -1]

3. Korpus erstellen

Erstellen Sie zunächst den ursprünglichen Korpus. Mit Hilfe meiner Freunde habe ich es mir so gemacht. ↓ スクリーンショット 2019-12-19 10.09.57.png ** * Aus urheberrechtlichen Gründen kann der Korpus nicht veröffentlicht werden, daher wird nur ein Teil davon eingeführt **

Ein Wort von Herrn S., einem Freund und Schöpfer des Korpus Dieses Mal nahm ich die Transkription mit der Intuition vor, dass "ich nicht weiß, aber es ist definitiv ein interessanter Typ." Das Kopieren und Einfügen mehrerer Sätze mit Kindles "Memo and Highlights" dauert eine ganze Woche. Um ehrlich zu sein, war es sehr schwierig. Sie können Seiten und Wetter kopieren und einfügen, während Sie Sätze ziehen. Wenn Sie dies jedoch tun, während Sie vom Kopieren und Einfügen der Arbeit erschöpft sind, fühlt es sich wie eine Rallye an. Zum Zeitpunkt der Lieferung wurde mir gesagt "Danke für den Korpus!", Aber jetzt gestehe ich, dass ich heimlich gegoogelt wurde, weil ich den "Korpus" nicht verstand.

4. Bereiten Sie ein Emotionswörterbuch vor

Bereiten Sie sich wie oben erwähnt auf die emotionale Analyse vor. Dieses Mal ist das Inui-Okazaki-Labor der Tohoku-Universität für die Öffentlichkeit zugänglich "Japanese Evaluation Polarity Dictionary" 2FJapanese% 20Sentiment% 20Polarity% 20Dictionary) wird teilweise neu organisiert und verwendet, um dem Inhalt des Wetterkindes zu entsprechen. Ich habe mein eigenes ** "Mehrwortwörterbuch" ** für die positive / negative Beurteilung durch mehrere Wörter wie [Mundwinkel + nach oben, +1] erstellt, die zuvor eingeführt wurden.

5. Geben Sie für jeden Satz einen emotionalen Wert an

Importieren Sie das Emotionswörterbuch und geben Sie den Emotionswert für jeden Satz aus. Der Code befindet sich am Ende dieses Artikels. Wenn Sie jedoch schnell und einfach japanische Emotionen analysieren möchten, ist die Bibliothek "oseti" sehr nützlich. Ich habe es auch als Referenz verwendet.

Die Sentiment Analysis-Bibliothek oseti für Python unter Verwendung des japanischen Bewertungspolaritätswörterbuchs wurde veröffentlicht

Ich habe ein Skript erstellt, das einen emotionalen Wert als Rückgabewert zurückgibt, wenn Text eingegeben wird, und den emotionalen Wert wie unten gezeigt zum Datenrahmen des Korpus hinzugefügt. スクリーンショット 2019-12-21 17.47.05.png

Spaltenbeschreibung

total_word_score_pair_list_abs1: Liste der morphologischen Elemente mit emotionalen Polaritätswerten und ihren emotionalen Werten sum_positive_srore: Summe der positiven Werte sum_pegative_srore: Summe der negativen Werte new_srore_sum: Die Summe aus positiven und negativen Werten

6. Zeichnen Sie den Übergang emotionaler Werte und vergleichen Sie ihn mit den Inhalten des Romans

Lassen Sie uns den emotionalen Wert mithilfe von Seaborn aus der Visualisierungsbibliothek grafisch darstellen. Summieren Sie die emotionalen Werte für jede Seite und betrachten Sie die ** Übergänge ** im Laufe der Zeit. Die x-Achse ist die Anzahl der Seiten und die y-Achse ist der Emotionswert. ** * Möglicherweise sind hier Spoiler enthalten. Achtung. </ font> **

Änderungen der emotionalen Werte von Seite zu Seite


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)

Hier sind die Ergebnisse! スクリーンショット 2019-12-18 22.39.29.png

Das Auf und Ab der Emotionen ist sehr intensiv! Positiv </ font> und Negativ </ font> wechseln sich ab. Was kann aus dieser Grafik gelesen werden

  • Positiv und Negativ erscheinen auf jeder Seite deutlich als Wellen
  • Es gibt Seiten mit extrem hohen positiven und negativen Werten ――Der emotionale Wert ändert sich (vielleicht) je nach Geschichte und Entwicklung. Die Wellen in der Grafik sind jedoch sehr fein und die Merkmale sind etwas schwer zu verstehen ...

Um eine etwas gröbere Funktion zu erhalten, ersetzen wir die Seiteneinheit x-Achse ** durch Kapiteleinheit ** und addieren sie.

Änderungen der emotionalen Werte nach Kapiteln


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

Was kann aus der Grafik abgelesen werden

--Kapitelbasierte Funktionen können globaler als seitenbasiert erfasst werden

  • Emotionale Werte sind in Wellen für jedes Kapitel groß, und in dem Kapitel unmittelbar nach dem Absinken des emotionalen Werts schwingt der emotionale Wert tendenziell positiv.
  • Es gibt keine Kapitel mit negativen emotionalen Werten in Kapiteleinheiten.

Das Auf und Ab von Emotionen ist leichter zu verstehen und zu interpretieren als zuvor!

Aber ... Sehen Sie sich die Werte der y-Achse im Diagramm an. Es gibt nur wenige negative </ font> Werte. Haben sich Menschen, die Filme und Romane gesehen haben, unwohl gefühlt?

** "Ist das Kind des Wetters nicht so eine friedliche Arbeit ...?" **

Gehen wir also noch einen Schritt weiter und analysieren. Als nächstes ist der emotionale Wert nicht der Gesamtwert, sondern wird in positiven Wert </ font> und negativen Wert </ font> ** unterteilt. Zeichnen Sie ein Diagramm.

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")

Das rote Diagramm ist der Übergang des positiven Werts </ font> und das blaue Diagramm der Übergang des negativen Werts </ font>. スクリーンショット 2019-12-19 11.23.04.png

Sowohl positive als auch negative Merkmale sind jetzt deutlich sichtbar! Wenn der positive und der negative Wert summiert und in einem Diagramm ausgedrückt werden, ** "Wenn sowohl die positiven als auch die negativen Werte große Werte zeigten, wurden die Werte versetzt und die Merkmale waren schwer zu erkennen." ** Es scheint, dass.

Lassen Sie uns nun einen kurzen Blick auf den Inhalt des Romans werfen.

Betrachtet man das Gesamtgefühl, so ist der Schwankungsbereich der emotionalen Werte zu Beginn und in der zweiten Hälfte der Geschichte groß. In Kapitel 2 und Kapitel 8 und höher sind sowohl der positive Wert </ font> als auch der negative Wert </ font> ziemlich hoch. Ist es der ** "ki" ** Teil und der ** "Übergang" ** Teil bei der Übertragung?

Schauen wir uns als nächstes die Größe des Wertes an.

Aus dieser Grafik ist ersichtlich, dass der positive Wert </ font> von Kapitel 8 und Kapitel 10 der größte und Kapitel 2 der größte negative </ font> ist.

chapter8 Kapitel 8 ist eine relativ friedliche Szene. Zusammen im Park spielen, sich mit Hinas jüngerem Bruder ** "Nagi" ** beraten oder einen Ring kaufen, damit ** "Hawaka" ** "Hina" ** gesteht ** Ich bin dabei zu gehen. Kein Wunder, dass der positive Wert </ font> hoch ist.

chapter10 Kapitel 10 ist der Höhepunkt der Geschichte. Dies ist eine Szene, in der ** "Segelhöhe" ** darum kämpft ** "Hina" ** zu helfen. Nicht nur positiver Wert </ font>, sondern auch negativer Wert </ font> ist hoch, sodass das Gefühl von ** "Segelhöhe" ** intensiv ist. Ich kann mir vorstellen, dass es so ist.

chapter2 Kapitel 2 ist die frühe Szene der Geschichte. Es ist eine Szene, in der "Hodaka", der sein Zuhause verlassen hat, nach Tokio kommt und versucht, einen Teilzeitjob zu finden, aber von den Wellen der Stadt niedergeschlagen wird und schließlich das Büro von ** "Suga" ** besucht und arbeitet. Wurde der negative Wert </ font> dort angezeigt, wo Sie von den Wellen der Stadt gerieben oder von ** "Suga" ** gescholten wurden?

7. Vergleichen Sie die emotionalen Werte für jeden Charakter

Vergleichen wir von hier aus die emotionalen Werte für jeden Charakter. Berechnen wir den durchschnittlichen emotionalen Wert pro Satz des Dialogs jedes Charakters.

So berechnen Sie den Durchschnittswert

** Emotionaler Gesamtwert des Dialogs jedes Charakters / Anzahl der Dialoge jedes Charakters **

Dieses Mal werden wir die vier Hauptfiguren ** "Hodaka" **, ** "Hina" **, ** "Suga" ** und ** "Natsumi" ** vergleichen.

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

Das Positive und das Negative sind klar zwischen Männern und Frauen getrennt.

Die Frauen sind wirklich positiv </ font>! Im Gegenteil, die beiden Männer sind ziemlich negativ </ font>.

Beide zeigen sehr nahe Werte. In der Tat, auch im Roman, die Hauptfiguren Hotaka und Suga

** "Diese beiden sind sehr ähnlich" **

Es gibt eine Darstellung, die von der Umgebung gesagt wird, aber Sie können sehen, dass sie in Bezug auf den emotionalen Wert ähnlich ist.

Schauen wir uns auch die positiven Werte </ font> und negativen Werte </ font> an.

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" ** scheint weniger negative </ font> Wörter zu sprechen als die drei. Was für ein starkes Mädchen ... ** "Natsumi" ** hat den höchsten positiven Wert </ font>, aber der negative Wert </ font> ist auch relativ hoch. ** "Natsumi" ** ist normalerweise ziemlich hell, aber es gibt verschiedene negative </ font> Wörter wie Selbsthass, weil man Schwierigkeiten hat, einen Job zu finden und sich bei Suga beschwert. Ich habe den Eindruck, dass Sie sprechen. Und der positive Wert </ font> von ** "Segelhöhe" ** ist ziemlich niedrig. Sicher gibt es nicht viel hellen Eindruck ... Aber wenn Sie das positive </ font> von ** "Hina" ** zieht, können diese beiden eine gute Kombination sein (?)

8. Gibt es einen Zusammenhang zwischen Wetter und emotionalen Werten?

Lassen Sie uns abschließend die Beziehung zwischen "Wetter" </ font> und emotionalen Werten untersuchen, die die Schlüssel zu dieser Geschichte sind. Die Methode besteht darin, den Durchschnittswert für jede Wetterszene wie im Fall von Zeichen zu berechnen. Die Wettertypen werden nach der Beschreibung bei der Erstellung des Korpus in die folgenden 6 Kategorien eingeteilt. "Sonnig" "Regen" "Leichter Regen" "Heavy_rain" "Klar" "Schnee" Es gibt drei Arten von Regenintensität, sodass Sie die Beziehung zwischen Regenintensität und emotionalem Wert erkennen können. Übrigens ist die Bühne der Geschichte (Tokio) aufgrund des Schauplatzes der Geschichte im Grunde genommen "Regen", außer wenn die Heldin ** "Hina" ** sich einen sonnigen Tag wünscht und wenn ** etwas passiert **. Es ist der Zustand von. Weil es jeden Tag regnet, möchte jeder in der Stadt, dass es klar wird.

Hypothese

** Die Hypothese ist, dass sonnige Szenen positiv </ font> sind und je stärker der Regen, desto negativ </ font>. ?? ** **.

Ich habe es erwartet. Mal sehen, das Ergebnis!

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

Immerhin ist sonnig das positivste </ font>! Es ist vorhersehbar! Es scheint nicht viel mit der Intensität des Regens zu tun zu haben. Obwohl "sonnig" sehr positiv ist, hat sich "klar" nicht wesentlich in positiv </ font> geändert. Warum...? Wie oben erwähnt, klärt sich das Wetter nur, wenn Hina sich einen sonnigen Tag wünscht und wenn etwas passiert **, aber das ** Ding ** ist ..... damit,

"Hina ist verschwunden" </ font>

Mit dem Verschwinden von Hina wird die Stadt, die bisher geregnet hatte, sofort klar. Die breite Öffentlichkeit, die nicht weiß, dass ** "Hina" ** geopfert wurde, ist jedoch gehorsam mit dem sonnigen Wetter zufrieden. Allerdings weiß das nur die Hauptfigur ** "Sail Height" ** und ist sehr traurig. Es sollte das beste Wetter in der Geschichte sein, aber hier gehen die Gefühle von "Segelhöhe" in die entgegengesetzte Richtung zur Welt. Obwohl es sonnig ist, wird es nicht sehr positiv.

In Bezug auf Schnee ist dies das negativste </ font>. Wenn Sie hier einen Film gesehen haben, werden Sie damit zufrieden sein. Dies ist der Höhepunkt, an dem ** "Segelhöhe" ** und ** "Hina" ** der Polizei entkommen und zum Love Hotel fliehen. Es ist eine Szene, in der es viele negative </ font> Ausdrücke gibt, weil die Welt und die Segelhöhen durch das extrem ungewöhnliche Wetter verwirrt sind, dass es schneit, obwohl es August ist.

9. Fazit

Was ich durch emotionale Analyse aus dem Roman gelernt habe ――Sie können die grobe Entwicklung der Geschichte und den Wendepunkt des Übergangs lesen. ――Sie können den Charakter des Zeichens grob anhand des positiven / negativen Werts beurteilen.

  • Der Übergang emotionaler Werte für jede Zeitreihe kann leicht interpretiert werden, indem sie Kapitel für Kapitel in positive und negative Werte unterteilt werden. Und dieses Mal habe ich die Beziehung zwischen dem Wetter und dem emotionalen Wert untersucht, was am einfachsten zu verstehen ist, aber es scheint, dass interessante Ergebnisse herauskommen werden, wenn ich auch die Beziehung mit anderen Faktoren untersuche. Wenn Sie eine Idee wie "Es wäre interessant, dies zu analysieren!" Haben, würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten.

10. Herausforderungen

Breites Spektrum an neuartigen Ausdrucksformen

Natürlich war ich vorbereitet, aber der Roman enthielt eine größere Bandbreite an Ausdrücken als erwartet, und es war schwierig, Wort für Wort positive Negative zu geben. In der letzten Szene ruft ** "Segelhöhe" ** "Das Wetter kann verrückt bleiben", aber es ist das stärkste positive </ font> in der Geschichte. Es ist eine schöne Szene, aber wenn Sie es wörtlich nehmen, wird es negativ sein. Es gibt eine Grenze, nur emotionale Werte in Worteinheiten anzugeben, und dies ist ein sehr schwieriger Ort.

11. Code

#Funktion zum Importieren des Emotionspolaritätswörterbuchs
def _make_dict():
    
    import pandas as pd
    
    df_word_dict = pd.read_csv('./dict/edited_target_pair_list_word_out.csv')#Substantiv
    df_wago_dict = pd.read_csv('./dict/edited_target_pair_list_wago_out.csv')#Wörter
    df_one_gram_dict = pd.read_csv('./dict/one_gram_dict_out.csv')#Mehrere Wörter

    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

#Eine Funktion, die Text Satz für Satz aufteilt
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 = ('Abwesend', '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 der emotionalen Werte, die dem Diktat entsprechen
        wago_polarities = [] # wago_Liste der emotionalen Werte, die dem Diktat entsprechen
        polarities_and_lemmanum = [] #Liste der endgültigen emotionalen Werte und des Lemmanums
        lemmas = [] #Stichwort,Wörter in der im Wörterbuch aufgeführten Form
        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 = '' #Vorläufig für die Fehlerbehandlung
        wago_polarity_word = '' #Vorläufig für die Fehlerbehandlung
        
        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#Zum Notieren der Reihenfolge der Wörter
        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
                #Verarbeitung von Lemma in Wörter in dem Format umgewandelt, das im Wörterbuch der geteilten Wörter aufgeführt ist
                #Dieses Wort ist Wort_Verarbeitung, wenn es diktiert ist

                if word_polarity_apeared and (feature[0] not in ['Hilfsverb','Partikel'] and last_hinsi not in ['Hilfsverb','Partikel'] and last_word not in ['Gibt es','Oru','Machen']) and last_word not in word_dict:
                    word_polarity_apeared = False  
                elif wago_polarity_apeared and (feature[0] not in ['Hilfsverb','Partikel'] and last_hinsi not in ['Hilfsverb','Partikel'] and last_word not in ['Gibt es','Oru','Machen']) and last_word not in wago_dict:
                    wago_polarity_apeared = False
                elif word_nutoral_polarity_apeared and (feature[0] not in ['Hilfsverb','Partikel'] and last_hinsi not in ['Hilfsverb','Partikel'] and last_word not in ['Gibt es','Oru','Machen']) and last_word not in word_dict:
                    word_nutoral_polarity_apeared = False
                elif wago_nutoral_polarity_apeared and (feature[0] not in ['Hilfsverb','Partikel'] and last_hinsi not in ['Hilfsverb','Partikel'] and last_word not in ['Gibt es','Oru','Machen']) 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_Da 0 im Voraus mit dict gelöscht wird, ist keine Verarbeitung erforderlich, aber lassen Sie es unter Berücksichtigung der Lesbarkeit.
                    else:
                        polarity = 0
                #word_Wenn es kein Wort im Diktat gibt
                except:
                    #wago_Wenn es ein Wort im Diktat gibt
                    try:
                        if wago_dict[lemma] in ['Positiv (Erfahrung)','Negativ (Erfahrung)','Positiv (Bewertung)','Negativ (Bewertung)']:
                            polarity = 1 if wago_dict[lemma] in ['Positiv (Erfahrung)','Positiv (Bewertung)'] else -1
#                             print(polarity)
                            wago_polarities.append([polarity,lemma_dict[lemma]])
                            wago_polarity_apeared = True
                            wago_polarity_word = lemma
                        elif wago_dict[lemma] == 'neutral':
                            wago_polarities.append([0,lemma_dict[lemma]])
                            wago_nutoral_polarity_apeared = True
                            wago_nutoral_word = lemma
                            polarity = 0
                        else:
                            polarity = 0
                     #word_diktieren auch wago_Verarbeitung, wenn das Wort kein Wort enthält
                    except:  
                        if word_polarity_apeared and surface in NEGATION and wago_nutoral_polarity_apeared is False:

                            if last_hinsi in ['Substantiv','Partikel','Hilfsverb','Verb','Adjektiv']:

                                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
                        #"Bitte reparieren" "Bitte verbessern"-Verarbeitung zu 1
                        elif lemma in ['Gib mir','wollen','Wunsch']:
                            
                            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]#Emotionswert-Grant 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]#Emotionswert-Grant 1
                                        wago_polarity_apeared = False
                                        wago_polarity_word = ''
                                        wago_polarities[-1][0] = -1
                                        polarity = 0
                            except:
                                polarity = 0
                                #Wenn am Ende des Satzes ein "ka" steht-Verarbeitung zu 1
                        elif last_hinsi in ['Hilfsverb','Partikel'] and lemma == 'Oder':
                            
                            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]#Emotionswert-Grant 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]#Emotionswert-Grant 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 ['Substantiv','Partikel','Hilfsverb','Verb'] and lemma in NEGATION:
                                lemma_type = 'Verweigerung'
                                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 ['Substantiv','Partikel','Hilfsverb','Verb'] 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
                    #Dieses Wort ist Wort_Was tun, wenn es nicht im Diktat war?
                        else:            
                        #Das Wort ist,Abwesend', 'Zu', 'Nu'Wenn ja, kehren Sie die Polarität des vorherigen Wortes um
                            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 ['Substantiv','Adjektiv','Hilfsverb']:

                                    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:
                                #Neutral + Verweigerungsverarbeitung
                                if last_hinsi in ['Verb','Partikel','助Verb'] and lemma in NEGATION:
                                    lemma_type = 'Verweigerung'   
                                    try:
                                        lemma_type = 'Verweigerung'
                                        wago_polarities[-1][0] += one_gram_dict[(wago_nutoral_word,lemma_type)]
                                        #Verarbeitung, um die Liste in umgekehrter Reihenfolge zu verfolgen
                                        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
                                #Andere Verarbeitung als neutral + Ablehnung
                                elif last_hinsi in ['Substantiv','Verb','Adjektiv','Partikel','助Verb'] :
                                    try:
                                        wago_polarities[-1][0] += one_gram_dict[(wago_nutoral_word,lemma)]
                                        #Verarbeitung, um die Liste in umgekehrter Reihenfolge zu verfolgen
                                        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_Aufsteigende Sortierung nach num
        try:
            polarities = _sorted_second_list(polarities_and_lemmanum)
        #Verwenden Sie nur Polaritätswerte ungleich Null. Wenn 0 bleibt, tritt bei der nachfolgenden Verarbeitung ein Fehler auf.
            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+'→ Bungal Der emotionale Wert am Ende des Satzes hat Vorrang')
#                 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):
            #Ersetzen Sie Sätze für die Emotionsanalyse. Beispiel: Nein → Nein
            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):
    #Eine Funktion, die eine Doppelliste glättet und sie zu einer Liste von nur Paaren mit emotionalen Werten macht
    return [e for inner_list in x for e in inner_list if e[1] !=0]

def score_sum_get(x):
    #_flatten_Eine Funktion, die die emotionalen Werte von abs1 summiert
    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


#Trainingsdaten lesen
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))
#Zählen Sie die Anzahl der Positiven pro Wort
df_tenki2['sum_positive_scores']=df_tenki2['positive_word_cnt_list'].apply(lambda x:sum(x))
#Zählen Sie die Anzahl der Negative pro Wort
df_tenki2['sum_negative_scores']=df_tenki2['negative_word_cnt_list'].apply(lambda x:sum(x))
#Mit emotionalen polaren Worten[Morphem,Emotionswert]Verarbeitung, um nur Paare von zu machen
df_tenki2['total_word_score_pair_list_abs1']=df_tenki2['total_word_score_pair_list'].apply(lambda x:_flatten_abs1(x))

#Berechnen Sie den gesamten emotionalen Wert
df_tenki2['new_score_sum']=df_tenki2['total_word_score_pair_list'].apply(lambda x:score_sum_get(x))

Recommended Posts