[Unity][Android][OculusQuest] 形態素解析MeCabを使ってみる


1.はじめに

OculusQuest(Android)で形態素解析を行ってみたかったので、その調査結果を載せておきます。
ちなみに自分のBlogでも同様の記事を作成しています。

2.検証した環境

・Unity 2018.4.1f1
・Oculus Quest

3.手順

(1) NMecabをダウンロードする
 NMeCabは、MeCabのエンジン処理を.NETで書き直してくれてたオープンソースです。
 Windows用にDLLが格納されていますが、今回はソースを使います。
 最新バージョンはNMecab0.07となります。(2019/9/25現在)
 https://ja.osdn.net/projects/nmecab/

(2)プロジェクト設定を行う
 NMeCabのソースを使う為に以下の設定を行います。
 ①.NET4 を使用するように設定する
 ② Allow unsafe Code にチェックする

 
(3)ソースと辞書ファイルを配置する
 ① UnityのAssetsフォルダに以下のフォルダを作成します。
  ・ Assets/NMecab
  ・ Assets/StreamingAssets/NMecab

 ②1.でダウンロードした圧縮ファイルの中にあるファイルを格納していきます。
  ・NMeCab0.07\src\LibNMeCab を Assets/NMecab 下にコピーします。

  ・NMeCab0.07\dic\ipadicの直下にあるすべての辞書ファイルを Assets/StreamingAssets/NMecab下にコピーします。

 (4)プログラムから呼び出す
 Androidの場合、StreamingAssetsに配置したファイルを読み込み場合、WWWを使って読み込む必要があります。そうなるとNMeCabのソースを変更しないといけなくなるので辞書ファイルは一旦OculusQuest(Android)端末へコピーしてからそのファイルを読み込むようにします。

 以下のスクリプトからのオブジェクトに張り付けて実行してみましょう。

MecabTest.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using NMeCab;
using System.IO;

public class MecabTest : MonoBehaviour
{

    void Update()
    {
    }

    void Start ()
    {
        //端末へMecabの辞書ファイルをコピー
        CopyFile(Application.streamingAssetsPath + "/NMeCab", Application.persistentDataPath, "char.bin");
        CopyFile(Application.streamingAssetsPath + "/NMeCab", Application.persistentDataPath, "dicrc");
        CopyFile(Application.streamingAssetsPath + "/NMeCab", Application.persistentDataPath, "matrix.bin");
        CopyFile(Application.streamingAssetsPath + "/NMeCab", Application.persistentDataPath, "unk.dic");
        CopyFile(Application.streamingAssetsPath + "/NMeCab", Application.persistentDataPath, "sys.dic");

        //Mecabの読み込み
        param = new MeCabParam();
        param.DicDir = Application.persistentDataPath;

        //テスト
        SetKeyWord("今日はとても良い天気ですね。");
    }

    /// 
    /// copy dictionary file.
    /// 
    /// void
    /// from path
    /// to path
    /// copy file name
    void CopyFile(string from, string to, string fileName) {
        string path = from + "/" + fileName;
        string toPath = to + "/" + fileName;

    #if UNITY_EDITOR || UNITY_IPHONE
        FileInfo file = new FileInfo(path);
        file.CopyTo(toPath, true);

    #elif UNITY_ANDROID
        WWW www = new WWW (path);
        while (!www.isDone) {
        }

        File.WriteAllBytes (toPath, www.bytes);
    #endif
    }


    /// 
    /// Shows the key word.
    /// 
    /// The key word.
    /// Sentence.
    public void SetKeyWord(string sentence) {
        MeCabTagger tagger = MeCabTagger.Create(param);
        MeCabNode node = tagger.ParseToNode(sentence);

        while (node != null)
        {
            if (node.CharType > 0)
            {
                //名詞のみ抽出
                if (node.Feature.IndexOf ("名詞") >= 0) {
                    Debug.Log ("名詞:" + node.Surface);
                }
            }
            node = node.Next;
        }
    }
}

Windows環境であれば辞書ファイルのコピーは不要なので、あくまでAndroid向けの処理となっています。
その辺は各自工夫してもらえれば良いかなと思います。