Javaで簡単に感情分析する方法

※サンプル・コード掲載

あらすじ

近年、AIの技術の活用分野は多岐に渡り、その中でも特に、人間の言葉を解釈する技術であるNLP(自然言語処理)が進歩してきています。

テキストマイニングや、対話システム等多岐に渡って使用され、人間のコミュニケーションを一部、チャットボットが代行するという所まで来ています。

今回は、そのNLPの一分野の感情分析と言われる分野で、テキストから人間の感情を読み取る技術について紹介をします。

この技術は、例えば、テキストに未成年に不適切な内容がある場合に、それをブロックするポルノフィルターや、暴力やヘイトスピーチを含んだ内容を検知する、オフェンシブフィルター等、実用的な活用が進んでいる分野です。

使用した環境

  • Windows or Macを仮定
  • Eclipse(Neon3)を使用
  • Java8.X(最新バージョン)を使用

形態素解析機器(Kuromoji)の準備

以下参照
Kuromoji(形態素解析)を2分で使えるようにする方法(Java)

評価極性辞書の使用

各単語を p = positive、e = neutral、n = negative の三つの評価に分類し、それを細かく、頻出単語毎にタグ付を人手で行った辞書の事を指しています。

この辞書の情報を元に、テキストの感情を特定する作業を行います。

今回の実習では、東北大学の乾・岡崎研究室が無料で配布している、日本語評価極性辞書 を使用する事とします。(pn.csv.m3.120408.trimをダウンロード)

中身を見て頂くと、以下のような構成になっており、p e nのタグ付がしてあります。

お礼 e ~する(行為)
お話 e ~する(行為)
お咎め n ~がある・高まる(存在・性質)
お洒落 p ~する(行為)
かい性 e ~がある・高まる(存在・性質)
・・・

この辞書を用いながら、実際にテキストの感情分析を行っていきましょう。

最速でJavaで感情分析を実装する方法

以下に、とりあえず、余り細かい事を気にしないで、最速でJavaで感情分析を実装する大まかな流れを示します。

  1. 評価極性辞書の読み込み
  2. テキストの形態素解析によるトークン化
  3. 感情スコアの算出

このような感じで、感情分析を行っていきます。それでは、以下、具体的な実装コードを見ていきましょう。

評価極性辞書の取り込み

以下のように、Mapに、単語をキーにして、その単語がpositiveの場合は+1、neutralの場合は0、negativeの場合は-1をスコアとして格納します。

File file = new File("pn.csv.m3.120408.trim"); // 評価極性辞書のロード 

BufferedReader br = new BufferedReader(new FileReader(file)); 

Map sentiMap = new HashMap<>(); // 評価極性辞書から読み込み、単語とスコアを保持したマップ

String str = br.readLine(); 
while (str != null) {
  String[] split = str.split("\t"); // タブで分割 
  if (split.length > 1) {
    String emotion = split[1].trim(); // p or e or n
    int sentiScore = 0;
    if (emotion.equals("p")) {
      sentiScore = 1; // pの場合+1
    } else if (emotion.equals("n")) {
      sentiScore = -1; // nの場合-1
    }
    sentiMap.put(split[0].trim(), sentiScore); // 単語とスコアの格納
  } 
  str = br.readLine();
}
br.close(); 

テキストの形態素解析によるトークン化

Kuromojiを用いて形態素解析を行い、トークンの表層情報を取得します。

String text = "好調で、アイデアが沸いてくる"; // 感情分析対象テキスト
Tokenizer tokenizer = Tokenizer.builder().build(); // Kuromojiオブジェクト作成
List tokens = tokenizer.tokenize(text); // Tokenize

for (Token token : tokens) {
	String surfaec = token.getSurfaceForm(); // トークンの表層取得
}

感情スコアの算出

トークンの表層情報が評価極性辞書に存在している場合、スコアを加算し、感情スコアを算出します。

感情スコアは、+1以上ならばPositive、0ならばneutral、-1以下ならばnegative

int sentiScore = 0; // 感情スコア、+1以上ならばPositive、0ならばneutral、-1以下ならばnegative

for (Token token : tokens) {
	String surfaec = token.getSurfaceForm(); // トークンの表層取得

	if (sentiMap.containsKey(surfaec)) {
		sentiScore += sentiMap.get(surfaec); // 評価極性辞書に単語が存在する場合、スコア加算
	}
}

System.out.println(sentiScore);

今回の対象文章「好調で、アイデアが沸いてくる」は、「好調」「アイデア」がそれぞれ、評価極性辞書上でpositiveと判断されているため、スコアは+2となり、positiveと判断されました。

実際の文章も前向きな内容なので、実感と合っているのではないでしょうか?

今回は、非常に簡単な方法で感情分析を実装する方法を示しましたが、この方法ではまだまだ課題があります。

例えば、以下のような「お役所仕事」というエントリが評価極性辞書にあります。

お役所仕事 n ~である・になる(評価・感情)主観

これに対して、Kuromojiは

お|役所|仕事

と分かち書きを行うので、トークンの表層情報を参照する場合、評価極性辞書にはヒットしません。

感情分析精度を上げていくためには、こういった部分について、改善が必要になってきます。

また、今回使用した評価極性辞書は、名詞にのみ対応しておりますが、その他の品詞に対応した辞書も併用する、等の工夫も必要になってきます。

その辺りの精度改善のテクニック等は、また次回解説をいたします。