Kuromojiについて

# Kuromojiについて
Kuromojiを使用するにあたっての雑記。ただのメモ。

## はじめに
Kuromojiは日本語形態素解析エンジンであるが、そもそも形態素解析とは何？ってとこから。

### 形態素解析とは
#### 文を単語に区切り品詞を定める処理
#### 以下の3つの処理を行っている
- 単語の分割
- 活用語処理（読みやすい形、意味のある形に変換すること）
- 品詞を定める
といった順番で行っている。

### 形態素解析の技術
#### 基本的な仕組み
- 単語辞書
- 形態素ラティス
- 最小コスト法

#### 単語辞書
形態素解析を行うにあたって、単語を分割する必要があるがどこで切ればいいかというのが課題。
ここで単語辞書というものを使用している。
単語辞書というのは10万以上の単語帳のようなもので、入力された文章に対して想定されるすべての分け方パターンを抽出されるのに使用される。
ただ、毎回検索していては計算時間が膨大にかかってしまうためツリー状に辞書の持ち方をして管理をしている。
下図のように1文字目、2文字目とたどっていくような辞書になっている。
白丸の場合は次がある場合、赤丸の場合は単語の終了として意味が通じるものを表している。

![tango](http://fc-handson.com/wp-content/uploads/2015/04/%E5%8D%98%E8%AA%9E%E8%BE%9E%E6%9B%B8.png)

#### 形態素ラティス
形態素ラティスとは単語辞書を用いて抽出したあらゆる単語の組み合わせの結果をグラフで表現した構造のことを指す。
下図の例では「東京都に住む」を入力した場合の形態素ラティスである。

![rates](http://fc-handson.com/wp-content/uploads/2015/04/%E5%BD%A2%E6%85%8B%E7%B4%A0%E3%83%A9%E3%83%86%E3%82%A3%E3%82%B9-1024x346.png)

#### 最小コスト法
最小コスト法とは、形態素ラティスの中でどれが一番正しいと思われる単語の分割の仕方なのかを判断するのに用いている。
コストとは具体的に
- 2つの単語の繋がりやすさ（連接コスト）
- 1つの単語の出現しやすさ（生起コスト）
の2つのことである。これらを各単語の辞書と共に持つことで計算できるようにしている。
たぶん、単語の繋がりやすさで一番自然なものを選んでくれてるイメージかな？

![minicost](http://fc-handson.com/wp-content/uploads/2015/04/%E6%9C%80%E5%B0%8F%E3%82%B3%E3%82%B9%E3%83%88%E6%B3%95.png)

上図の例でいうと東京|都|に|住むといったコストが一番低いといった結果なので
形態素解析の結果は「東京|都|に|住む」になる。
これは、あくまで最もそうだと思われるパターンを出力しているだけなので、間違ったケースも出力される。特にひらがなとか。。
※日本人も読み間違えるので自然っちゃ自然

以上が形態素解析自体のざっくりとした説明。

## Kuromoji概要
KuromojiはJavaで書かれているオープンソースの日本語形態素解析エンジン。
辞書が内包されており、使用している辞書はMeCab-IPADIC辞書。
ここでいう辞書っていうのは形態素解析する際に利用している単語帳みたいなもの。
日本語で分かち書き（言葉区切りに空白をおくこと）するために形態素解析の際には単語辞書というものを利用している。
形態素解析の仕組みは以下参考。

## 機能・特徴

### 機能
- 複合語の分割…テキストを言葉に分割（形態素）
- 品詞のタグ付け…言葉分類の割当（名詞、動詞、助詞、形容詞など）
- 見出し化…活用の動詞や形容詞に辞書の見出しを表示
- 読み方…漢字の読み方を抽出

### 特徴
- 実用的なパッケージング…必要なものが全て含まれるjarファイルとしてある
- 検索用の設計…検索リコールを改善するため複合プレーズを分割するモード 
- 簡単に利用…簡単な利用のため使いやすいAPIおよびMavenインテグレーション 
- 実用的なライセンス …オープンソースも商業用ソフトウェアでも適用できるApache v2ライセンス 

## 記法
Javaを使用したいくつかのサンプル。

### Tokenクラスで取得できる情報
KuromojiはTokenizerクラスを初期化→tokenize()メソッドの引数に形態素解析する単語を入力して結果を受け取るといった形で実行する
以下、参考。

#### 例1)形態素解析
Tokenizerインスタンスを初期化してtokeniser.tokenize(解析したい文章)の書式で行える。

``` java:形態素解析
Tokenizer tokenizer = Tokenizer.builder().build();
		List<Token> tokens = tokenizer.tokenize("もう眠い");

		for (Token token : tokens) {
			System.out.println("====================");
			// allFeatures tokenの全ての要素を出力
			System.out.println("allFeatures: " + token.getAllFeatures());
			// partOfSpeech 品詞など形態素上で意味のある言葉を出力
			System.out.println("partOfSpeech: " + token.getPartOfSpeech());
			// position 単語の位置を出力
			System.out.println("partOfSpeech: " + token.getPosition());
			// reading カナ読みを出力
			System.out.println("reading: " + token.getReading());
			// surfaceForm 元の単語を出力
			System.out.println("surfaceFrom: " + token.getSurfaceForm());
			// allFeaturesArray allFeaturesをArray型で返す
			System.out.println("allFeaturesArray" + token.getAllFeaturesArray());
			// isKnown 辞書にある言葉かどうか
			System.out.println("isKnown: " + token.isKnown());
			// isUnknown 辞書にない言葉かどうか、isKnownと反対の結果が出力される
			System.out.println("isUnKnown: " + token.isUnknown());
			// isUser ユーザーで定義した言葉かどうか
			System.out.println("User: " + token.isUser());
}

```

``` java:出力結果

====================
allFeatures: 副詞,一般,*,*,*,*,もう,モウ,モー
partOfSpeech: 副詞,一般,*,*
partOfSpeech: 0
reading: モウ
surfaceFrom: もう
allFeaturesArray[Ljava.lang.String;@30dae81
isKnown: true
isUnKnown: false
User: false
====================
allFeatures: 形容詞,自立,*,*,形容詞・アウオ段,基本形,眠い,ネムイ,ネムイ
partOfSpeech: 形容詞,自立,*,*
partOfSpeech: 2
reading: ネムイ
surfaceFrom: 眠い
allFeaturesArray[Ljava.lang.String;@1b2c6ec2
isKnown: true
isUnKnown: false
User: false
====================

```


#### 例2)モードを使い分けてみる
Kuromojiでは形態素解析するにあたってモードの指定が行える。
モードは3種類ある。
- ノーマルモード

通常モード初期化したらデフォルトでこの形式で形態素解析を行いますよーといったもの。

- Searchモード

「日本経済新聞」のような複数の言葉が組み合わさった単語を「日本 | 経済 | 新聞」のように分けて解析してくれる。全文検索エンジンと組み合わせて利用する場合に、日本経済新聞が「経済」や「新聞」でも検索可能になるので便利。 

- Extendsモード

Searchモードに加えて、未知語をuni-gramとして扱う。たとえば「モバゲー」は「モ | バ | ゲ | ー」と1文字ごとに分割される。未知語を検索し損ねることを減らしてくれそうな機能。 


``` java:モードを使い分けてみる

        String parseWord = "日本経済新聞でモバゲーの記事を読んだ";
        Builder builder = Tokenizer.builder();

        // ノーマルモード
		Tokenizer normal = builder.build();
		List<Token> tokenNormal = normal.tokenize(parseWord);

		// Searchモード
		builder.mode(Mode.SEARCH);
		Tokenizer search = builder.build();
		List<Token> tokenSearch = search.tokenize(parseWord);

		// Extendsモード
		builder.mode(Mode.EXTENDED);
		Tokenizer extended = builder.build();
		List<Token> tokenExtended = extended.tokenize(parseWord);

```

``` java:出力結果

// ノーマルモード
=> 日本経済新聞 | で | モバゲー | の | 記事 | を | 読ん | だ

// Searchモード
=> 日本 | 経済 | 新聞 | で | モバゲー | の | 記事 | を | 読ん | だ

// Extendsモード
=> 日本 | 経済 | 新聞 | で | モ | バ | ゲ | ー | の | 記事 | を | 読ん | だ

``` 

#### その他
他にできることとして
- ユーザ辞書の利用

Builderにユーザ辞書を渡してその場で辞書をカスタマイズすることができる。
特定の単語についてだけ追加したいといった対応は指定して行ったほうが良いかもしれない。

- UniDicの利用

Unidicという辞書の利用にもKuromojiは対応しているらしい。
必要になったら利用するのもいいかもしれない。


## 参考

### 形態素解析
日本語形態素解析の裏側を覗く！MeCab はどのように形態素解析しているか-クックパッド開発者ブログ-
http://techlife.cookpad.com/entry/2016/05/11/170000

MeCab 汎用日本語形態素解析エンジン
http://chasen.naist.jp/chaki/t/2009-09-30/doc/mecab-cabocha-nlp-seminar-2009.pdf

技術的側面からの検索エンジンの考察 ~第1回　テキストマイニングの基本中の基本、形態素解析とBOWとは~
http://mieru-ca.com/blog/research-basics-of-text-mining/


### Kuromoji
Java製形態素解析器「Kuromoji」を試してみる
http://www.mwsoft.jp/programming/lucene/kuromoji.html

Java：kuromojiを使って形態素解析してみる 
http://www.hiihah.info/index.php?Java%EF%BC%9Akuromoji%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B

(GAEで日本語の形態素解析を試してみる)第3回　Kuromojiを使ってみる
https://shun1adhocblog.wordpress.com/2013/04/05/gae%e3%81%a7%e6%97%a5%e6%9c%ac%e8%aa%9e%e3%81%ae%e5%bd%a2%e6%85%8b%e7%b4%a0%e8%a7%a3%e6%9e%90%e3%82%92%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b%e7%ac%ac3%e5%9b%9e%e3%80%80kuromoji%e3%82%92/