(編集:私の古い答えは、PatternAnalyzerではなく、一般的な分類子に関するものでした)
TextBlob は、コードで「PatternAnalyzer」を使用します。その動作は、そのドキュメントで簡単に説明されています: http://www.clips.ua.ac.be/pages/pattern-en#parser
次のことがわかります。
pattern.en モジュールは、製品レビューで頻繁に発生する形容詞(例: 良い、悪い、驚くべき、苛立たしいなど)のレキシコンをバンドルし、感情の極性(ポジティブ ↔ ネガティブ) と主観性 (客観 ↔ 主観)のスコアで注釈を付けます。 .
センチメント() 関数は、含まれる形容詞に基づいて、指定された文の (極性、主観性) タプルを返します。
アルゴリズムの動作を示す例を次に示します。極性は、使用される形容詞に直接依存します。
sentiment_analyzer.analyze('player')
Sentiment(polarity=0.0, subjectivity=0.0)
sentiment_analyzer.analyze('bad player')
Sentiment(polarity=-0.6999998, subjectivity=0.66666)
sentiment_analyzer.analyze('worst player')
Sentiment(polarity=-1.0, subjectivity=1.0)
sentiment_analyzer.analyze('best player')
Sentiment(polarity=1.0, subjectivity=0.3)
専門的なソフトウェアは、通常、ニューラル ネットワークと分類子に基づく複雑なツールを字句解析と組み合わせて使用します。しかし、私にとっては、TextBlobは文法分析(ここでは形容詞の極性)からの直接的な結果に基づいて結果を出そうとしているだけです。それが問題の原因です。
一般的な文が否定的かどうか ("not" 単語を使用)をチェックしようとはしません。形容詞が否定されているかどうかを確認しようとします (一般的な構造ではなく、形容詞でのみ機能するため)。ここで、best は名詞として使用され、形容詞の否定ではありません。したがって、極性はプラスです。
sentiment_analyzer.analyze('not the best')
Sentiment(polarity=1.0, subjectivity=0.3)
単語の順序を入れ替えて、文全体ではなく形容詞を否定します。
sentiment_analyzer.analyze('the not best')
Sentiment(polarity=-0.5, subjectivity=0.3)
ここでは、形容詞が否定されています。したがって、極性はマイナスです。その「奇妙な行動」についての私の説明です。
実際の実装はファイルで定義されています:
https://github.com/sloria/TextBlob/blob/dev/textblob/_text.py
介在部分は次の式で与えられます。
if w in self and pos in self[w]:
p, s, i = self[w][pos]
# Known word not preceded by a modifier ("good").
if m is None:
a.append(dict(w=[w], p=p, s=s, i=i, n=1, x=self.labeler.get(w)))
# Known word preceded by a modifier ("really good").
...
else:
# Unknown word may be a negation ("not good").
if negation and w in self.negations:
n = w
# Unknown word. Retain negation across small words ("not a good").
elif n and len(w.strip("'")) > 1:
n = None
# Unknown word may be a negation preceded by a modifier ("really not good").
if n is not None and m is not None and (pos in self.modifiers or self.modifier(m[0])):
a[-1]["w"].append(n)
a[-1]["n"] = -1
n = None
# Unknown word. Retain modifier across small words ("really is a good").
elif m and len(w) > 2:
m = None
# Exclamation marks boost previous word.
if w == "!" and len(a) > 0:
...
「not a good」または「not the good」と入力すると、単一の形容詞ではないため、else 部分に一致します。
「良くない」部分が合うelif n and len(w.strip("'")) > 1:
ので極性が逆になります。not the good
どのパターンとも一致しないため、極性は「best」と同じになります。
コード全体は一連の微調整、文法指示 (たとえば、! を追加すると極性が増し、スマイリーを追加すると皮肉を示すなど) です。いくつかの特定のパターンが奇妙な結果をもたらすのはそのためです。それぞれの特定のケースを処理するには、文がコードのその部分の if 文のいずれかと一致するかどうかを確認する必要があります。
私が助けてくれることを願っています