Simpleな入力予測アプリをRで作った

Data Science Specialization courseの課題で、Swiftkeyのような入力予測アプリを作った。自然言語処理の分野における機械学習のアプリケーション適用例で、実際にアプリケーションにするためには、いかに予測精度を維持しながら、応答速度を満足するように構築する必要がある。今回言語は英語で、Swiftkeyが公開しているblog、twitter、newsのデータベースを元にモデル化をした。

Simple入力予測アプリ
https://norihiton.shinyapps.io/NextWordPrediction/

Code
https://github.com/NorihitoN/nextWordPrediction

以下にアプリケーションの構築手順と改善点等をまとめた。

  1. Rにおける言語解析用のPackageについて
  2. 文書データのコーパスとトークン化
  3. N-gram法によるトークン化と文書行列の作成
  4. Shinyによるウェブアプリケーション化

1. Rにおける言語解析用のPackageについて

Rには自然言語処理用のPackageが準備されているが、特徴やパフォーマンスを考慮して選択する必要がある。
参考:https://github.com/lgreski/datasciencectacontent/blob/master/markdown/capstone-ngramComputerCapacity.md

テキスト分析用にCRAN Task View for Natural Language Processing でリストされているPackageを挙げてみる。

ngramは高速だが、機能はngramの作成に限定される。RWeka と tm はテキストマイニングの様々な関数があるが、速度が遅いため、大きなコーパスを扱いづらい。quanteda は様々なテキスト分析の関数が用意されており、パフォーマンスも非常に良いため、quantedaを使用した。

2. 文書データのコーパス作成とトークン化

quantedaの使い方は、quantedaクイック・スタートガイドを参照した。

トレーニングセットは以下からダウンロードした。
https://d396qusza40orc.cloudfront.net/dsscapstone/dataset/Coursera-SwiftKey.zip

コーパス作成

ダウンロードデータからbase packageのreadLines()を用いてデータを読み込み、corpus()でコーパスを作成。初めはtm packageのVcorpus()を使用したが、quantedaのcorpus()の方が圧倒的に速い。

トークン化

テキストをトークン化するために,quanteda のtokens()関数を使った。英語のテキストでは、スペースで区切られた文字が、文字ベクトルのトークンのリストとしてオブジェクトが生成される。オプションで、ピリオドやシンボルの除去などの操作ができる。

3. N-gram法によるトークン化と文書行列の作成

N-gram法によるトークン化には、先ほどのtoken()を用いた。tokens()には、オプションでngramsを指定できる。
n-gramについてはWikipedia を参照。やってみるとわかるが、ngram数を増やすほど、テキストに出現する単語列のパターンが多くなるため、トレーニングデータに対する精度は上がるが、訓練データの予測精度が悪くなる(過学習)が起きる。サンプルアプリケーションでは3-gramsまでを使用した。

N-gram法によりトークン化されたオブジェクトが作成できたら、文書行列を作成する。これはdfm()(document-feature-matrix)によって行われ、各テキストとそれに含まれるトークン(n個の単語列)のカウント数を返してくれる。

dfm()により文書行列ができたら、非常に簡単な予測モデルを作成する。今回は3-gramでアプリケーションを作るので、インプットされたテキストの最後の2つの単語を読み取り、文書行列を検索し、カウント数が多い3-gramのトップ3をアウトプットする。

4. Shinyによるウェブアプリケーション化

ShinyはRでウェブアプリケーションを簡単に作り、デプロイできるpackage。
今回は、テキストをインプットして投稿できるようなアプリにしてみた。テキストインプットの際に、作成した予測モデルを使って、次に予測される単語を表示するようにした。

5. 課題

精度の向上

ユーザの入力を助けるアプリなので、予測精度をあげることが一番の課題である。n-gram法では、文書行列にない文字列は予測されないため、精度をあげるにはデータを増やすしかない。一方でデータを増やすと、文書行列の容量が非常に大きくなるため、モデルの構築に非常に時間がかかる、またアプリケーションに適用する際に、データベースを作る必要がある。今回は100MB以下になるように使用するデータセットを制限した。以下に考えられる手段を挙げた。

  • トークン化する単語の前処理

文書には意味のある文字以外にも、句読点やシンボル、数字、絵文字など様々な文字が混在している。今回はピリオドとシンボルを除外したが、目的によっては、除外する文字をより選別する必要がある。

  • 文書行列にない入力があった際の対処

一般にSmoothingと呼ばれ、いくつか方法があるが、Katz's back-off modelはその一つ。3-gramで該当する予測文字がなかった場合には2-gramを用いて検索を行う。

  • 別のモデルを使用する

n-gram法ではなく、ベイズ推定など他の方法を使用する。

参考
https://en.wikipedia.org/wiki/N-gram
https://en.wikipedia.org/wiki/Katz%27s_back-off_model
http://www.cs.cornell.edu/courses/cs4740/2014sp/lectures/smoothing+backoff.pdf

Scroll to top