[PYTHON] Wie wäre es mit einer Polaritätsanalyse mit hinzugefügtem "Auftrag"?

Ich habe mit einem kleinen Rhythmus etwas über die japanische Polaritätsanalyse (Emotionsanalyse) gelernt, und obwohl ich ein Amateur war, habe ich damit herumgespielt.

Bei der allgemeinen Polaritätsanalyse (Emotionsanalyse) wird die Punktzahl jedes Wortes im Vergleich zum Polaritätswörterbuch für den gesamten Satz gemittelt. Aber gibt Ihnen das immer eine intuitive Punktzahl ...?

Verarbeitung natürlicher Sprache Adventskalender 2019 Es ist der 4. Tag. Gestern kabayan55 ["Eine Geschichte für" Menschen, die die Verarbeitung natürlicher Sprache studieren möchten "](https://kabayan55.hatenablog.com/entry / 2019/12/03/001554) und Kazumasa Yamamoto „Dokumentkategorisierung mit spaCy CLI lernen“ / kyamamoto9120 / items / 84d62c3b33fb77c03fbe) Es war.

Ich nehme zum ersten Mal am Adventskalender teil, freue mich aber auf die Zusammenarbeit mit Ihnen.

Was ist Polaritätsanalyse?

Viele Leute denken, dass es ** positive Abdruckwörter ** und ** negative Abdruckwörter ** gibt. Zum Beispiel hat "** hell " bei vielen Menschen einen positiven Eindruck und " dunkel **" einen negativen Eindruck.

** Polaritätsanalyse ** dient dazu, die Eindrücke (Polarität) jedes Wortes zusammenzufassen und die Polarität jedes im Satz vorkommenden Wortes zu analysieren.

Die Polaritätsanalyse wird als Sprungbrett für die ** Emotionsanalyse ** verwendet. Im Falle eines insgesamt positiven Satzes ist es ein vernünftiger Grund, dass der Verfasser (Sprecher) ein positives Gefühl hat. ~~ Es ist wie eine Kyoto-Person ... ~~

In dieser Reihe von Prozessen ist ** die Gültigkeit des Wörterbuchs **, dh ob ** die Polarität des Wortes richtig bewertet wird **, ein sehr wichtiger Gesichtspunkt, aber dieses Mal werde ich nicht darauf eingehen und dann * * Wir werden uns auf den Teil konzentrieren, der die Polarität des gesamten Satzes berücksichtigt **.

Polaritätsbewertungsbibliothek für Python "oseti"

Es gibt verschiedene polare Wörterbücher, aber diesmal japanische Bewertungspolarwörterbücher, veröffentlicht vom Inui Suzuki Laboratory Ich werde 20Resources% 2FJapanese% 20Sentiment% 20Polarity% 20Dictionary verwenden. Dieses Wörterbuch wird Wort für Wort mit 1 für positiv und -1 für negativ bewertet.

Eine Bibliothek, die dieses polare Wörterbuch in Python leicht verfügbar macht, ist "oseti", die auch in Qiita angekündigt wird. Es berechnet die Punktzahl des Satzes durch die morphologische Analyse von MeCab.

Lassen Sie es uns als Test verwenden. Die Installation von MeCab entfällt. Da oseti in PyPI registriert ist, können Sie es mit dem Befehl pip installieren.

pip install oseti

Sie können die Punktzahl berechnen, indem Sie eine "Analyzer" -Instanz erstellen und eine Methode aufrufen.

import oseti

analyzer = oseti.Analyzer()

Lassen Sie uns vorerst den Anfang dieses berühmten Satzes weitergeben.

Ich bin eine Katze. Es gibt noch keinen Namen. Ich habe keine Ahnung, wo ich geboren wurde. Ich erinnere mich, wie ich an einem dunklen und feuchten Ort geweint habe. Ich habe hier zum ersten Mal Menschen gesehen. Außerdem hörte ich später, dass es die schlimmste Rasse von Menschen namens Shosei war.

―― „Ich bin eine Katze“ ―― Soseki Natsume

iamcat = 'Ich bin eine Katze. Es gibt noch keinen Namen.\n \
Ich habe keine Ahnung, wo ich geboren wurde.\
Ich erinnere mich, wie ich an einem dunklen und feuchten Ort geweint habe.\
Ich habe hier zum ersten Mal Menschen gesehen.\
Außerdem hörte ich später, dass es die schlimmste Rasse von Menschen namens Shosei war.'

iamcat_score = analyzer.analyze(iamcat)
print(iamcat_score)
[0, 0, 0, -1.0, 0, 1.0]
  1. Satz,

Ich erinnere mich, an einem dunklen und feuchten Ort geweint zu haben.

Ich kann verstehen, dass dies als negativ beurteilt wird, aber der 5. Satz,

Außerdem hörte ich später, dass es die schlimmste Rasse von Menschen namens Shosei war.

Es ist ein wenig seltsam, dass als positiv behandelt wird. In diesem Fall rufen wir die Methode auf, die eine detaillierte Analyse durchführt.

iamcat_detail = analyzer.analyze_detail(iamcat)
print(iamcat_detail[3])
print(iamcat_detail[5])
{'positive': [], 'negative': ['dim'], 'score': -1.0}
{'positive': ['Ichiban'], 'negative': [], 'score': 1.0}

Nun, das scheint der Grund zu sein, warum das Wort Nummer eins positiv behandelt wird.

Lassen Sie uns einen Satz mit einer Mischung aus positiven und negativen Wörtern übergeben.

test_text = 'Ich habe ein neues Smartphone gekauft und obwohl es mich viel gekostet hat, ist die Bedienung leicht und komfortabel.'
test_score = analyzer.analyze(test_text)
test_detail = analyzer.analyze_detail(test_text)
print(test_score)
print(test_detail)
[0.3333333333333333]
[{'positive': ['Licht', 'gemütlich'], 'negative': ['Ausgaben'], 'score': 0.3333333333333333}]

Die Punktzahl jedes Wortes ist ** gemittelt **. Der Durchschnitt scheint eine ** Standardmethode ** zu sein, die häufig in anderen Artikeln zur Polaritätsanalyse verwendet wird.

Wenn Sie im Durchschnitt in Schwierigkeiten sind

Übrigens gibt es fiktive Figuren, Mr. Sato und Mr. Suzuki. Das Gespräch zwischen den beiden ist so.

Sato "Ich war neulich für eine Geschäftsreise in einer Stadt. ** Ich war müde, weil sich viele Menschen verlaufen haben, aber das Essen war köstlich und die Landschaft war gut **."

Suzuki "Das war gut. Ich ging nach B City, aber ** die Landschaft war gut und das Essen war köstlich, aber ich war müde und verloren, wohin ich auch ging **."

Herr Sato scheint Sightseeing genossen zu haben **, aber Herr Suzuki scheint ** nicht gut ** gewesen zu sein.

Wenn jedoch die Polaranalyse dieser beiden Bemerkungen durchgeführt wird, wird es so.

sato_remark = 'Ich war müde, weil es viele Menschen gab, die sich oft verirrten, aber das Essen war köstlich und die Landschaft war gut.'
suzuki_remark = 'Die Landschaft war gut und das Essen war köstlich, aber ich war müde und verloren, wohin ich auch ging'

sato_score = analyzer.analyze(sato_remark)
suzuki_score = analyzer.analyze(suzuki_remark)
print(F'Sato: {sato_score}')
print(F'Suzuki: {suzuki_score}')
Sato: [0.0]
Suzuki: [0.0]

Beide sind auf genau die gleiche Weise zu ** Pramai Zero ** geworden. Sie können den Grund dafür sehen, indem Sie die detaillierte Analysemethode aufrufen.

sato_detail = analyzer.analyze_detail(sato_remark)
suzuki_detail = analyzer.analyze_detail(suzuki_remark)
print(F'Sato: {sato_detail}')
print(F'Suzuki: {suzuki_detail}')
Sato: [{'positive': ['köstlich', 'Aussicht'], 'negative': ['Hau ab', 'Müde'], 'score': 0.0}]
Suzuki: [{'positive': ['Aussicht', 'köstlich'], 'negative': ['Müde', 'Hau ab'], 'score': 0.0}]

Ja, beide verwenden die gleichen bewerteten Wörter. Kurz gesagt, was Sie sagen, ist dasselbe.

Wir sind jedoch der Meinung, dass die Bemerkungen von Herrn Sato positiv und die Bemerkungen von Herrn Suzuki negativ sind. Was ist der Grund?

Eine Hypothese wäre die Reihenfolge der Themen. Zumindest scheinen Japaner eher zu sagen, was sie später sagen wollen als **. Es ist für Herrn Sato selbstverständlich zu denken, dass Zögern und Müdigkeit im Vergleich zur Köstlichkeit des Essens und der Schönheit der Landschaft nicht so wichtig sind, und das Gegenteil für Herrn Suzuki.

Gewicht in der Reihenfolge des Aussehens

Fügen wir also eine Methode hinzu, die die Wörter in der Reihenfolge gewichtet, in der sie erscheinen.

import neologdn
import sengiri
def analyze_with_weight(self, text, weightfunc=None):
    if weightfunc is None:
        weightfunc = lambda x: [1 / x for _ in range(x)]
    text = neologdn.normalize(text)
    scores = []
    for sentence in sengiri.tokenize(text):
        polarities = self._calc_sentiment_polarity(sentence)
        if polarities:
            weights = weightfunc(len(polarities))
            scores.append(sum(weights[i] * p[1] for (i,p,) in enumerate(polarities)))
        else:
            scores.append(0)
    return scores
setattr(oseti.Analyzer, 'analyze_with_weight', analyze_with_weight)

Wenn Sie weightfunc eine Ganzzahl geben, geben Sie ihr eine Funktion, die eine eindimensionale Sequenz mit dieser Anzahl von Elementen (eine Liste, ein Taple oder ein NumPy-Tensor) zurückgibt (ich erwarte eine Summe von 1). Ich habe es nicht besonders überprüft). Dies ist das Gewicht in der Reihenfolge des Auftretens. Wenn nicht angegeben, ist das Gewicht gleichmäßig. Dies entspricht dem Durchschnitt.

Geben Sie beispielsweise Folgendes als linear ansteigendes Gewicht an:

from fractions import Fraction
def linear_weight(x):
    l = [i for i in range(1, x + 1)]
    s = sum(l)
    return [Fraction(i, s) for i in l]

Wenn man dieses Gewicht verwendet, um ihre Bemerkungen zu analysieren, sieht es so aus.

sato_score = analyzer.analyze_with_weight(sato_remark, linear_weight)
suzuki_score = analyzer.analyze_with_weight(suzuki_remark, linear_weight)
print(F'Sato: {sato_score}')
print(F'Suzuki: {suzuki_score}')
Sato: [Fraction(2, 5)]
Suzuki: [Fraction(-2, 5)]

Hoppla, es blieb eine rationale Zahl.

sato_score = [float(i) for i in sato_score]
suzuki_score = [float(i) for i in suzuki_score]
print(F'Sato: {sato_score}')
print(F'Suzuki: {suzuki_score}')
Sato: [0.4]
Suzuki: [-0.4]

Daher wurde die Bemerkung von Herrn Sato als relativ positiv und die Bemerkung von Herrn Suzuki als relativ negativ beurteilt. Ist das nicht intuitiver als das erste Ergebnis?

Aber Worte sind nicht so einfach

Dies bedeutet jedoch nicht, dass diese Methode alles lösen wird.

score = analyzer.analyze_with_weight('Wenn überhaupt, ist es eine angenehme Müdigkeit.', linear_weight)
score = [float(i) for i in score]
print(score)
[-0.3333333333333333]

In einigen Fällen, wie in diesem Beispiel oder in der Redewendung, kann das vorhergehende Akronym wirklich bedeuten. Es kann ziemlich gewalttätig sein, es einfach schwerer zu machen, ohne solche Feinheiten zu berücksichtigen. Sie müssen "Kontext" lesen.

Wenn Sie eine „korrektere“ Bewertung erhalten möchten, wird die Methode immer komplizierter. Aber,

Statistisch ausgefeilte oder komplexe Methoden liefern nicht unbedingt genauere Vorhersagen als einfachere. - Statistisch ausgefeilte oder komplexe Methoden liefern nicht immer genauere Vorhersagen als präzise Methoden.

――“The M3-Competition: results, conclusions and implications” - Spyros Makridakis, Michele Hibon

Ebenso führt eine zu komplizierte Methode nicht immer zu guten Ergebnissen. Es ist vielmehr nicht sinnvoll, Kosten zu zahlen, die sich nicht lohnen, selbst wenn Sie gute Ergebnisse erzielen.

In diesem Sinne ist "Durchschnitt" extrem einfach und kann ein guter Weg sein, um anständige Ergebnisse zu erzielen ....

abschließend

Es war also ein verschiedener Satz von Tanuki wie ** Ich kenne nicht einmal den Charakter der Verarbeitung natürlicher Sprache **.

Morgen ist Herr Mona Cat.

Weiter: Verwenden wir den verteilten Ausdruck von Wörtern schnell mit fastText!

Recommended Posts

Wie wäre es mit einer Polaritätsanalyse mit hinzugefügtem "Auftrag"?
Anmerkungen zu mit
[Python] Vergleichen von Datum und Uhrzeit mit der hinzugefügten Zeitzone
Die Geschichte, wie theano mit TSUBAME 2.0 verwaltet wurde
Datenanalyse mit Python 2
Korbanalyse mit Spark (1)
Abhängigkeitsanalyse mit CaboCha
Sprachanalyse mit Python
Sprachanalyse mit Python
Führen Sie eine Regressionsanalyse mit NumPy durch
Datenanalyse mit Python
Eine Geschichte über den Umgang mit dem CORS-Problem