読者です 読者をやめる 読者になる 読者になる

Rを通じて統計学を学ぶ備忘録ブログ

SPSSからRに移行したい私のような人向けのR解説ブログ兼学習用備忘録。

テキストマイニングはじめました〜その4〜

テキストマイニング

テキストマイニングのことを書き始めてはや4つ目です。今回の記事の目的は以下の通りです。

docMatrix()関数、docMatrix2()関数、docMatrixDF()関数、文書行列の重み付けの理解

気にしてないと思いますが、今回使用するフォントは「青柳衡山フォントT」です。書家の青柳衡山先生が揮毫及び作成された毛筆フォントです。 f:id:teruaki-sugiura:20160503222641p:plain Rヘルプによれば、docMatrix()関数は「指定されたディレクトリ内のすべてのテキストファイルのターム行列を作成する関数」のようです。基本的なUsageは以下のとおりです。

docMatrix( mydir, pos = "Default", minFreq = 1, weight ="no", kigo=0, co = 0)
mydir:テキストファイルへのパス
pos:抽出する品詞(指定しない時はデフォルトで名詞と形容詞が抽出される。"記号"を指定するとタームとして記号を含める。c("名詞", "動詞")のように指定します。
minFreq:最小値制限。どれかのテキストファイルで、minFreq回以上の頻度でなければ、0とする。
kigo:記号をTOTAL-TOKENSに含める場合は1を指定
weight:重み付けターム行列を作成する場合は"tf*idf"=TF/IDF法を指定。"tf*idf*norm"はTF/IDF法を正規化したもの。

docMatrix()関数のテキストの読み込み方法が少し特殊で、例えばフォルダAの中にあるテキスト001~テキスト010の10個のテキストデータを同時に読み込み、ターム行列を作成してくれるのです。そのため、mydirでは「フォルダA」を指定する必要があります。作成されたターム行列は行にターム、列に各テキストが割り当てられます。論より証拠なので、早速ターム行列を作成してみます。今回は、フォルダ「okazakifolder」の中にある「okazaki1~okazaki6」までの6個のテキストデータを同時に読み込ませ、minFreq=2に設定し、TOTAL-TOKENS、LESS-THAN-2の行を削除します。

t <- docMatrix(mydir = "okazakifolder", pos = c("名詞"), minFreq = 2) 
t <- t[ row.names(t) != "LESS-THAN-2" , ]
t <- t[ row.names(t) != "TOTAL-TOKENS" , ]

f:id:teruaki-sugiura:20160503230138p:plain ここでややこしいのがminFreqの解釈です。例えば、minFreq=2に設定すると、「ある文書Aに××というタームが2回使われていた場合、文書B,Cで1回使われていても、それは0とみなし、文書Aの××の頻度を2と計測する」というように解釈しなければいけません。実際は「移籍」というタームは、okazaki3.txtにも出現していますが0になっています。比較のために、minFreq=1に設定し、各行において合計が2個以上のタームのみ出現するようにフィルタリングしてみます。

t <- docMatrix(mydir = "okazakifolder", pos = c("名詞"), minFreq = 1) 
t <- t[ row.names(t) != "LESS-THAN-1" , ]
t <- t[ row.names(t) != "TOTAL-TOKENS" , ]
t <- t[ rowSums(t) >= 2, ]

f:id:teruaki-sugiura:20160503230946p:plain 先ほどのターム行列とは少し中身が異なります。各文書で1回のみ出現しているタームも表示されています。 f:id:teruaki-sugiura:20160503233553p:plain Rヘルプによれば、docMatrix2()関数は「指定されたディレクトリ内のファイルやすべてのテキストファイルのターム行列を作成する関数」です。基本的なUsageは以下のとおりです。

docMatrix2( directory, pos = "Default", minFreq = 1, weight ="no", kigo=0, co = 0)
directory:テキストファイルへのパス
pos:抽出する品詞(指定しない時はデフォルトで名詞と形容詞が抽出される。"記号"を指定するとタームとして記号を含める。c("名詞", "動詞")のように指定します。
minFreq:各文書を通じた最小値制限。すべてのテキストファイルを行方向に合計し、minFreq回以上の頻度であれば計測する。
kigo:記号をTOTAL-TOKENSに含める場合は1を指定
weight:重み付けターム行列を作成する場合は"tf*idf"=TF/IDF法を指定。"tf*idf*norm"はTF/IDF法を正規化したもの。
co:共起行列の作成する場合は1を指定する

先ほどのdocMatrix()関数との違いはminFreqの制限方法です。 各タームを行方向に合計していき、設定値よりも大きければ各文書の内の数値を計測して表示します。rowSums(t)>=xxと考え方は同じですね。とりあえずターム行列を作成してみます。

t <- docMatrix2(directory = "okazakifolder", pos = c("名詞"), minFreq = 3)

f:id:teruaki-sugiura:20160503234849p:plain docMatrix2()関数では、TOTAL-TOKENS、LESS-THAN-xの行は作成されないようです。 f:id:teruaki-sugiura:20160503235034p:plain これはRMeCabDF()関数と同じような機能を持つ関数です。Rヘルプによれば、docMatrixDF()関数は「データフレーム内の指定列のターム行列を作成する関数」です。基本的なUsageは以下のとおりです。

docMatrixDF( charVec = c("dataframe"), pos= "Default", minFreq = 1, weight = "no", co = 0)
charVec:文書の列
その他オプション:docMatrix系と同じ。
tdat <- read.csv("xxxx.csv", header = TRUE)
t <- docMatrixDF( charVec = tdat[, "comment"], pos= "Default", minFreq = 1, weight = "no", co = 0)

f:id:teruaki-sugiura:20160504002604p:plain ここでは、ターム行列の重み付けについて考えます。なぜ、重み付けをする必要があるのでしょうか。理由は単純で、分量が長ければ長いほど特定のタームの頻度が多く計測されてしまいます。そのため、タームに重み付けることによって、相対的な重要度を検討しなければ、ミスリードにつながってしまいます。言い換えれば、似ている文書ならば、文書量に比例して、そのタームの頻度も比例してしまうからです。ではどのような重み付け方法があるのでしょうか。主に以下の3つの方法を組み合わせることによって、ターム行列を重み付けしていきます。 f:id:teruaki-sugiura:20160504004527p:plain 局所的重み付け(Local Weight)は索引語頻度(TF:Term Frequency)とも呼ばれるようです。この方法は、文書内に表れる頻度が高いタームに大きな重みをかける方法。基本的に頻度が重みとして割り当てられる。頻度1なら重み1のような感じ。 f:id:teruaki-sugiura:20160504004528p:plain 大域的重み付け(Grobal Weight)は文書頻度逆数(IDF:Inverse Docment Frequency)とも呼ばれます。文書集合という全体を考えた上で、タームに重み付けを行う方法。文書頻度逆数という言葉が気になります。要するに、頻出するタームは重要ではなく、「逆」に頻出しないタームが重要とかんがえると、名前の由来が腑に落ちます。 f:id:teruaki-sugiura:20160504011932p:plain Nは文書の数、n_iは対象のタームが含まれる文書の数によって定義されます。 f:id:teruaki-sugiura:20160504004529p:plain 正規化(Normalization)は、文書の長さに応じて重みを調整する方法。RMeCabではcos正規化を用いて、正規化が行われます。つまり、各文書のベクトルのノルムを計算して、その文書の各ターム頻度をノルムで割ったもの。TF-IDF方法およびその正規化は以下の通りです。 f:id:teruaki-sugiura:20160504013252p:plain f:id:teruaki-sugiura:20160504013316p:plain 例として、TF-IDF方法で重み付けをしたターム行列を正規化してみます。比較しやすいように画像を並べています。左が重み付けターム行列、右がただのターム行列です。

t <- docMatrix("doc", pos = c("名詞"), weight = "tf*idf*norm")

f:id:teruaki-sugiura:20160504014329p:plain

以上で今回はお終い。次回はNgramについて勉強していきます。

広告を非表示にする