Rのngramパッケージを使ってnグラムを作る

概要
Rでnグラムを生成するためのパッケージの紹介。あまり使い勝手は良くない。

nグラムの生成

Rでnグラムを生成するためのパッケージ ngram について紹介する。ngram はCRANを通じて配付されているので、Rで install.packages(“ngram”) と入力すれば簡単にインストールできる。ただ、このパッケージはできることが少なく、使い勝手は総じて良くない。

このパッケージを使ってnグラムを作るには、文字列が入った変数を引数にとって ngram 函数を使えば良い。例えば、以下の例では“A cat chased a rat. A dog chased a cat.”という文字列から2グラムを作っている。

> library(ngram)
> string <- "A cat chased a rat. A dog chased a cat."
> # 無指定で ngram を使うと2グラムになる。
> bigram <- ngram(string)

ngramコマンドは無指定の場合、2グラムを生成する。他の数のnグラムを生成したければ、数値を指定する必要がある。例えば、3グラムを生成したい場合は、ngram(string, 3) とする。

作られたnグラムの中身を見るには、以下のように、print 関数を使う。full=TRUE と指定する必要があることに注意。

> # 作られた ngram の中身を見る
> print(bigram, full=TRUE)
rat. A 
dog {1} | 

a cat. 
NULL {1} | 

dog chased 
a {1} | 

cat chased 
a {1} | 

chased a 
rat. {1} | cat. {1} | 

A dog 
chased {1} | 

a rat. 
A {1} | 

A cat 
chased {1} | 

この出力結果では、2グラムの後に来る単語も合わせて出力される。

また、生成したnグラムを文字列のベクトルとして出力する函数として、get.ngrams がある。

> # すべてのnグラムを文字列のベクトルとして出力する
> get.ngrams(bigram)
[1] "rat. A"     "a cat."     "dog chased" "cat chased" "chased a"  
[6] "A dog"      "a rat."     "A cat"  

nグラムデータからの文のランダム生成

ngram函数を使ってnグラムデータを生成した後、そのnグラムデータから文をランダム生成することも可能である。文をランダム生成するにはbabble函数を使う。babble函数の引数としては、nグラムのデータと、生成する文の長さを示す数値がある。

> library(ngram)
> string <- "A cat chased a rat. A dog chased a cat."
> bigram <- ngram(string)
> # 10語の文を生成
> babble(bigram, 10)
[1] "rat. A dog chased a rat. A dog chased a "

preprocess 函数による前処理

ngramパッケージに付属する preprocess を使うと、ngramにする際に便利なように文字列をきれいにしてくれる。具体的には、余計な空白を削除したり、大文字・小文字をそろえたり、句読点を単語から切り離したりする。

> library(ngram)
> string <- "A   cat   chased    a   rat.   A dog   chased a cat."
> preprocess(string)
[1] "A cat chased a rat. A dog chased a cat."
> string <- "A   cat   chased    a   rat.   A dog   chased a cat."
> # 余計な空白を削除する
> preprocess(string)
[1] "A cat chased a rat. A dog chased a cat."
> # 余計な空白を削除して、すべて小文字にする
> preprocess(string, case="lower")
[1] "a cat chased a rat. a dog chased a cat."
> # 余計な空白を削除して、すべて大文字にする
> preprocess(string, case="upper")
[1] "A CAT CHASED A RAT. A DOG CHASED A CAT."
> # 余計な空白を削除して、
> # 句読点の前後に空白を入れて単語から切り離す
> preprocess(string, split.at.punct=TRUE)
[1] "A cat chased a rat . A dog chased a cat ."