※サンプル・コード掲載
あらすじ
近年、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で感情分析を実装する大まかな流れを示します。
- 評価極性辞書の読み込み
- テキストの形態素解析によるトークン化
- 感情スコアの算出
このような感じで、感情分析を行っていきます。それでは、以下、具体的な実装コードを見ていきましょう。
評価極性辞書の取り込み
以下のように、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は
お|役所|仕事
と分かち書きを行うので、トークンの表層情報を参照する場合、評価極性辞書にはヒットしません。
感情分析精度を上げていくためには、こういった部分について、改善が必要になってきます。
また、今回使用した評価極性辞書は、名詞にのみ対応しておりますが、その他の品詞に対応した辞書も併用する、等の工夫も必要になってきます。
その辺りの精度改善のテクニック等は、また次回解説をいたします。