Unityで形態素解析する方法



Unityで形態素解析する方法についてまとめようと思います


#そもそも形態素解析とは？#

形態素解析とは、文章を意味のある単語に区切り、辞書を利用して品詞や内容を判別することを意味します


##1.Yahoo!APIを使う##

Yahooが提供しているAPIに形態素解析をしてくれるものがあります

UnityからYahooにwwwでリクエストを送ることで、形態素解析結果を受け取ることが出来ます

ただし、受け取るファイルはxml形式、
24時間以内で1つのアプリケーションIDにつき50000件のリクエストが上限となっています

詳しくは[公式ページ](http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html)を参照してください

コード例は以下の様になります

```csharp:summary.cs
using UnityEngine;
using System.Collections;
using System.Xml;
public class summary : MonoBehaviour {
 
	public IEnumerator Start() {
 
		// リクエスト先は仮
		string url = "http://";
		WWW www = new WWW(url);
		//  wait until HTML Contents will come 
		yield return www;
 
		if(www.error != null){
			Debug.Log("Error!");
		}else{
			Debug.Log("Success");
				XmlDocument xmlDoc = new XmlDocument();
				xmlDoc.LoadXml(www.text);
 
				// 目的のノードだけを取り出す
			XmlNodeList levelsList = xmlDoc.GetElementsByTagName("word_list");
			foreach(XmlNode levelInfo in levelsList){
				Debug.Log(levelInfo.Name.ToString());
				XmlNodeList levelcontent = levelInfo.ChildNodes;
				foreach(XmlNode levelsItens in levelcontent){
					foreach(XmlNode word in levelsItens){
					if(word.Name == "surface")
					{
							Debug.Log(word.InnerText.ToString());
					}
					}
 
				}
			}
 
				}
 
				}
 
		}
```


リクエストURLは自分が何を受け取りたいかを考えてオプションを決める必要があります

例：文章から名詞だけを取り出して、表示するリクエストURL
http://jlp.yahooapis.jp/MAService/V1/parse?appid=
<あなたのアプリケーションID>&results=ma&filter=9&response=surface
&sentence=<解析する文章>

渡す文章はWWW.EscapeURL(解析する文章)とエンコードした方が良いです


##2.NMeCabを使う##


>NMeCabは、オープンソース形態素解析エンジンMeCabの解析処理部分を、.NETライブラリとして移植したものです。
オリジナル版MeCabと同じ辞書を使用し、同じ解析結果を得ることができます。
純粋なC#言語で作成されており、ラッパーではないため、インストールがシンプルで、高速性と安定性にも優れています。[NMeCab - 形態素解析エンジンMeCabの.NET版](http://sourceforge.jp/projects/nmecab/)

上記サイトから、最新版をダウンロードします(2014/11/13時点で0.06.4が最新)


![01.png](https://qiita-image-store.s3.amazonaws.com/0/59429/8158bde5-ece0-88ee-c7a4-6222cd567812.png)

ダウンロードしたフォルダから、dicフォルダとLibNMeCab.dllをUnityに持って行きます

画像のNcab.csというファイルは自分が作成したものです

[NMeCabで形態素解析してみよう](http://qiita.com/jacoyutorius/items/7f1867ae2de0da64ec46)のコードを元に動かしてみます

辞書ファイルの位置を自分で作ったフォルダ構成に応じて変える必要があります

コード例は以下の様になります


```csharp:Ncab.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NMeCab;
 
public class Ncab : MonoBehaviour {
 
	// Use this for initialization
	void Start () {
 
		string sentence = "Unityで形態素解析";
 
			MeCabParam param = new MeCabParam();
		param.DicDir = @"Assets/NMeCab0.06.4/dic/ipadic";
 
			MeCabTagger t = MeCabTagger.Create(param);
			MeCabNode node = t.ParseToNode(sentence);
			while (node != null)
			{
				if (node.CharType > 0)
				{
					Debug.Log(node.Surface + "\t" + node.Feature);
				}
				node = node.Next;
			}
			Debug.Log("");
		}
 
}
```

実行結果
![02.png](https://qiita-image-store.s3.amazonaws.com/0/59429/69b01d40-6334-0d3c-14b3-e83d1be0a2a2.png)

*注意*
*NMeCabをAndroidで使う方法(Unity)を現在探しています.
情報を持っていらっしゃる方、是非コメント欄にてご教示ください.*


##3.TinySegmenter.NETを使う##

品詞等は判別出来ませんが、分かち書きするだけならこちらが便利です

分かち書きとは文章において語と語の区切りを付けることを意味します

例えば、「私はUnityが好きです」を分かち書きすると

私|は|Unity|が|好き|です　と、なります

使い方：[ここ](http://wiki.dobon.net/index.php?free%2FTinySegmenter.NET%2F0.1.1)からTinySegmenter.csをダウンロードします

Assetsの中にPluginsフォルダを作って、その中にTinySegmenter.csを入れます

![03.png](https://qiita-image-store.s3.amazonaws.com/0/59429/da81b949-e408-4367-3420-e439fbb2be49.png)

エラーが出るかと思いますが

Edit -> Project Settings -> Player -> Api Compatibility Levelを .NET2.0にすることで消えます

![04.png](https://qiita-image-store.s3.amazonaws.com/0/59429/fdb193f1-3f01-2ae3-bda7-147106864859.png)
コード例は以下の様になります

```csharp:Tiny.cs
using UnityEngine;
using System.Collections;
 
public class Tiny : MonoBehaviour {
 
	// Use this for initialization
	void Start () {
		string text = "私はUnityが好きです";
 
		//TinySegmenterオブジェクトを作成する
		TinySegmenterDotNet.TinySegmenter seg = new TinySegmenterDotNet.TinySegmenter();
		//分かち書きを行う
		string[] words = seg.Segment(text);
		//"|"で区切って表示する
		Debug.Log(string.Join("|", words));
	}
 
	
}
```

実行結果
![05.png](https://qiita-image-store.s3.amazonaws.com/0/59429/98d8c460-a98f-2e7c-e82c-049aa6fbe050.png)

以上がUnityだけで形態素解析する主な方法だと思われます

勿論、サーバー側のPHPやPythonの方で形態素解析して、それをUnityに送る方法もあるかと思います