LoginSignup
0
1

More than 1 year has passed since last update.

【kuromoji】Android(Kotlin)でスタンドアロンで形態素解析をする方法

Last updated at Posted at 2023-03-05

この記事を書いた経緯

Andoridで形態素解析をしたくて色々と調べていたのですが、

  • 情報が少ない
  • あっても情報が古くて、そのままだと動かない

という状況だったので、このような記事を書きました。

概要

Android端末でスタンドアロンで形態素解析をする方法を紹介します。
形態素解析にはkuromojiというオープンソース日本語形態素解析エンジンを使います。

形態素解析とは

Wikipediaでは以下のような説明がなされています。

形態素解析(けいたいそかいせき、Morphological Analysis)とは、文法的な情報の注記の無い自然言語のテキストデータ(文)から、対象言語の文法や、辞書と呼ばれる単語の品詞等の情報にもとづき、形態素(Morpheme, おおまかにいえば、言語で意味を持つ最小単位)の列に分割し、それぞれの形態素の品詞等を判別する作業である。

例えば、今日はかつ丼を食べたという文であれば、文を次のように分割します。

今日 / は / かつ丼 / を / 食べた

その上で、それぞれの単語の品詞などを求めます。

単語 品詞
今日 名詞
助詞
かつ丼 名詞
助詞
食べ 動詞
助動詞

Web茶まめというサイトで手軽に形態素解析ができるので、色々な文を形態素解析してみると理解しやすいかもしれません。

形態素解析するための手順

使用するkuromoji

今回は次のkuromojiを使用します。

1. 初期設定

任意の設定

説明を簡略化するために、初期設定は以下のようにしました。この設定は任意であるので、別の設定をしても形態素解析はできます。

  • テンプレートはEmpty Activityを選択

必須の設定

kuromojiを使うためには、以下の設定が必要です。この設定をしないとビルドしたときにエラーが出ます。

  • Minimum SDKを26以上に設定

2. app/build.gradle

今回はkuromojiを使うので、dependencies { } の中に以下を記載します。

app/build.gradle
implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'

このままSync Nowをしてビルドすると、次のようなエラーが出ます。

2 files found with path 'META-INF/CONTRIBUTORS.md'.
Adding a packagingOptions block may help, please refer to https://developer.android.com/reference/tools/gradle-api/7.4/com/android/build/api/dsl/ResourcesPackagingOptions
for more information

そのため、android { } の中に以下を記載します。

app/build.gradle
packagingOptions {
    resources.excludes.add("META-INF/*")
}

この状態でSync Nowをしてビルドすると、今度は成功するはずです。

3. activity_main.xml

今回はTextViewに形態素解析した結果を表示します。そのため、以下のようにactivity_main.xmlにidtext_viewであるTextViewを記載してください。

activity_main.xml
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/text_view"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

4. MainActivity.kt

MainActivityは以下のようにします。
packageの部分はご自身で決めたパッケージ名にしてください。
下記のコードでは、kuromojiのトークナイザのインスタンスを生成し、今日はかつ丼を食べたという結果を文を形態素解析し、結果(単語とその品詞)をTextViewにセットしています。

MainActivity.kt
package com.example.ktkuromojiipadic

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import com.atilika.kuromoji.ipadic.Tokenizer

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val inputText = "今日はかつ丼を食べた"
        val tokenizer = Tokenizer()
        val tokens = tokenizer.tokenize(inputText)
        val textView = findViewById<TextView>(R.id.text_view)

        var outputText = ""
        for (token in tokens) {
            outputText += token.surface + ":" + token.partOfSpeechLevel1 + "\n"
        }

        textView.text = outputText
    }
}

5. 実行結果

実行結果は以下のようになりました。
かつ丼以外は正常に形態素解析ができたことが分かります。かつ丼はおそらくデフォルトの辞書に登録されていなかったため、上手く形態素解析がされなかったのだと思います。この後の章で、辞書にかつ丼を追加することで、この問題を解決します。

形態素解析_1.png

辞書に新たな単語を登録するための手順

目標

先ほど上手く形態素解析ができなかったかつ丼を辞書に追加することで、正常に形態素解析ができるようにしていきたいと思います。

1. ユーザー辞書の用意

テキストファイルの作成

まず、Assetsフォルダを用意します。作り方を以下のような記事を参考にしてください。

つぎに、作成したAssetsフォルダの中に、userdictionary.txtという名前のファイルを作ります。ファイルの名前はなんでもいいのですが、今回はこの名前でいきます。

ユーザー辞書の作成

ファイルができたら、かつ丼を辞書に追加していきます。辞書の形式は以下の記事を参考にしました。

この記事によると辞書の形式は、単語, 分割後の単語の形, 読み方, 品詞となるそうです。

品詞の種類は以下の記事を参考にしました。

今回はかつ丼を辞書に追加したいので、userdictionary.txtに以下のように書き込みます。

userdictionary.txt
かつ丼,かつ丼,カツドン,名詞

2. ユーザー辞書の利用

ユーザー辞書を読み込むために、前回のMainActivityを以下のように変更します。

MainActivity.kt
package com.example.ktkuromojiipadic

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import com.atilika.kuromoji.ipadic.Tokenizer

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val inputText = "今日はかつ丼を食べた"

        // 変更点 開始
        val assetManager = resources.assets
        val file = assetManager.open("userdictionary.txt")
        val tokenizer = Tokenizer.Builder().userDictionary(file).build<Tokenizer>()
        // 変更点 終了

        val tokens = tokenizer.tokenize(inputText)
        val textView = findViewById<TextView>(R.id.text_view)

        var outputText = ""
        for (token in tokens) {
            outputText += token.surface + ":" + token.partOfSpeechLevel1 + "\n"
        }

        textView.text = outputText
    }
}

3. 実行結果

実行結果は以下のようになりました。
かつ丼が期待通りに形態素解析されていることが分かります。

形態素解析_2.png

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1