More Related Content Similar to R による文書分類入門 (20) More from Takeshi Arabiki (16) R による文書分類入門2. 自己紹介
• Takeshi Arabiki
‣ 平凡な Web エンジニア(主に JavaScript)
‣ Twitter & はてな: @a_bicky & id:a_bicky
‣ e-mail:
• 興味など
機械学習、自然言語処理
• ブログ
あらびき日記 http://d.hatena.ne.jp/a_bicky/
6. 形態素解析
• 文を形態素(意味の最小単位)に分割
‣ 日本語自然言語処理における 単語 はたいてい形態素のこと
‣ e.g. 「お酒」→「お」+「酒」(形態素の定義は曖昧)
• 各形態素の品詞推定
‣ e.g. 「お(接頭詞)」+「酒(名詞)」
自然言語で書かれた文を形態素(Morpheme, おおまかにいえば、言語で意
味を持つ最小単位)の列に分割し、それぞれの品詞を判別する作業を指す。
引用: 形態素解析 - Wikipedia
つまり・・・
7. mecab による形態素解析
$ mecab
ハードルは高ければ高いほどくぐりやすい
ハードル 名詞,一般,*,*,*,*,ハードル,ハードル,ハードル
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
高けれ 形容詞,自立,*,*,形容詞・アウオ段,仮定形,高い,タカケレ,タカケレ
ば 助詞,接続助詞,*,*,*,*,ば,バ,バ
高い 形容詞,自立,*,*,形容詞・アウオ段,基本形,高い,タカイ,タカイ
ほど 助詞,副助詞,*,*,*,*,ほど,ホド,ホド
くぐり 動詞,自立,*,*,五段・ラ行,連用形,くぐる,クグリ,クグリ
やすい 形容詞,非自立,*,*,形容詞・アウオ段,基本形,やすい,ヤスイ,ヤスイ
EOS
入力文
出力
8. ベクトル空間モデル
• 素性 (feature) の取り方はいろいろ
• Unigram model (Bag-of-Words model)
‣ 1つの単語を1つの素性とする
‣ 単語の出現順は考慮しない(文書を単語の袋詰めとみなす)
e.g. 「赤ちゃんと僕」と「僕と赤ちゃん」は同じベクトルになる
• N-gram model
‣ 連続する n 単語を1つの素性とする
e.g. 「赤ちゃんと僕」→ <s>赤ちゃん, 赤ちゃんと, と僕, 僕</s>
「僕と赤ちゃん」→ <s>僕, 僕と, と赤ちゃん, 赤ちゃん</s>
そせい
文書をベクトル空間の1点として表現する
9. 単語の重み付け
• TF (Term-Frequency) 値
‣ 各文書における単語の出現頻度
• IDF (Inverse Document Frequency) 値
‣ コーパス(文書集合)内で対象の単語を含む文書の割合の逆数の対数
• TF-IDF 値
‣ TF 値と IDF 値を掛けあわせた値
‣ 特定の文書にだけ出現する単語の値が大きくなる
cf. 情報検索アルゴリズム 3.2 節参照
idf(t, D) = log
|D|
|{d|d ∈ D, t ∈ d}|
tfidf(t, d, D) = tf(t, d)idf(t, D)
tf(t, d) = |{x|x ∈ d, x = t}|
10. 単語文書行列
D =
d1 d2 · · · dM
t1 0 1 . . . 0
t2 2 0 . . . 0
...
...
...
...
...
tV 1 0 . . . 2
各文書ベクトルを列に並べた行列
e.g. あるコーパスに対する TF 値による単語文書行列
文書 の文書ベクトル
文書 における単語 の出現回数
d2
dM tV
11. 単語文書行列の作成
> library(RMeCab)
>
> pos <- c("名詞", "動詞", "形容詞", "副詞", "連体詞")
> texts <- c("ハードルは高ければ高いほどくぐりやすい",
+ "タダより高いものはない")
>
> D1 <- docMatrixDF(texts, pos = pos, weight = "tf")
to make data frame
# 抽出する形態素の品詞
RMeCab を使うことで手軽に単語文書行列が作成可能
# TF 値による単語文書行列を作成
12. > D1
OBS.1 OBS.2
1 0
0 1
0 1
1 0
0 1
1 0
2 1
単語文書行列の作成
くぐる
ない
もの
やすい
タダ
ハードル
高い
RMeCab を使うことで手軽に単語文書行列が作成可能
13. N-gram による行列
>
> D2 <- t(docNgramDF(texts, type=1, pos=pos, N=2))
number of extracted terms = 7
to make matrix now
> D2
Row1 Row2
1 0
0 1
0 1
1 0
1 0
0 1
1 0
[くぐる-やすい]
[もの-ない]
[タダ-高い]
[ハードル-高い]
[高い-くぐる]
[高い-もの]
[高い-高い]
# 2-gram (bigram) による行列を作成
15. 疎行列への変換
> library(Matrix)
> (sm <- as(D1, "CsparseMatrix"))
7 x 2 sparse Matrix of class "dgCMatrix"
OBS.1 OBS.2
1 .
. 1
. 1
1 .
. 1
1 .
2 1
くぐる
ない
もの
やすい
タダ
ハードル
高い
# CSC 形式の疎行列に変換
16. > str(sm)
Formal class 'dgCMatrix' [package "Matrix"] with 6
slots
..@ i : int [1:8] 0 3 5 6 1 2 4 6
..@ p : int [1:3] 0 4 8
..@ Dim : int [1:2] 7 2
..@ Dimnames:List of 2
.. ..$ : chr [1:7] "くぐる" "ない" "もの" "やすい" ...
.. ..$ : chr [1:2] "OBS.1" "OBS.2"
..@ x : num [1:8] 1 1 1 2 1 1 1 1
..@ factors : list()
疎行列の構造
行のインデックス (0-origin)
列の開始ポインタ (0-origin)
非零の要素の値
17. CSC 形式
CSC (= Compressed Sparse Column)
i 0 3 5 6 1 2 4 6
x 1 1 1 2 1 1 1 1
(i,j) (0,0) (3,0) (5,0) (6,0) (1,1) (2,1) (4,1) (6,1)
p 0 4 8
0 列目はここから
1 列目はここから
18. 疎行列の操作
> sm[c(3, 5), ]
2 x 2 sparse Matrix of class "dgCMatrix"
OBS.1 OBS.2
. 1
. 1
> colSums(sm)
[1] 5 4
> rowSums(sm)
[1] 1 1 1 1 1 1 3
> as.matrix(sm[c(3, 5), ])
OBS.1 OBS.2
0 1
0 1
# 3行目と5行目を抽出
もの
タダ
# 各文書の単語数を算出
# 各単語の出現回数を算出
もの
タダ
# 普通の行列に変換
基本的な操作は普通の行列と同様に行うことが可能
21. サンプルデータ
> library(maxent) # cf. help(maxent)
> data <- read.csv(system.file("data/NYTimes.csv.gz",
+ package = "maxent"))
>
> subdata <- subset(data, Topic.Code %in% c(16L, 20L))
>
> topic <- factor(subdata$Topic.Code)
> corpus <- Corpus(VectorSource(subdata$Title))
>
> D <- as.matrix(t(DocumentTermMatrix(corpus)))
maxent パッケージの New York Times データを使用
# 2クラス分類なので Topic.Code が 16 と 20 のものだけ使用
# クラスラベル
# 単語文書行列
22. サンプルデータ
>
> rownames(D)[which(rownames(D) == "...")] <- "X..."
> set.seed(0)
>
> trainIndex <- sample.int(ncol(D), ncol(D) * 0.5)
> trainData <- t(D[, trainIndex])
> testData <- t(D[, -trainIndex])
> trainTopic <- topic[trainIndex]
> testTopic <- topic[-trainIndex]
# データの半分を学習データとして使用
# rpart でエラーになるので単語名を変更
maxent パッケージの New York Times データを使用
25. 確率的言語モデル
• 単語列 の同時確率 を与えるモデル
• 文書の生成方法をモデル化
‣ に従って単語列を生成することで文書を生成可能
wN
1 = w1w2 · · · wN
w N
M
unigram の例(各単語が独立と仮定)
P(wN
1 )
P(wN
1 )
P(d) = P(wN
1 ) =
N
i=1
P(wi)
26. Unigram Mixtures
w N
M
クラスごとに unigram を割り当てるモデル
• カテゴリの異なる文書は単語の出現確率も異なるはず
• 各文書は1つのクラス(トピック)から生成されると仮定
P(d) =
y
P(y)
N
i=1
P(wi|y)
ˆy = arg max
y
N
i=1
P(wi|y)P(y)
ナイーブベイズはこの値を最大化するクラスを真のクラスと推定する
y
28. ナイーブベイズを実装
myNaiveBayes - function(x, y) {
lev - levels(y)
ctf - sapply(lev, function(label) {
colSums(x[y == label,])
})
ctp - t(t(ctf + 1) / (colSums(ctf) + nrow(ctf)))
nc - table(y, dnn = NULL)
cp - nc / sum(nc)
structure(list(lev = lev, cp = cp, ctp = ctp),
class = myNaiveBayes)
}
# 各クラスにおける単語出現頻度
# ラプラススムージングによるクラスごとの単語の出現確率
# 各クラスの生成確率
# 各クラスに所属する文書数
30. R でナイーブベイズ
model - myNaiveBayes(trainData, trainTopic)
pred - predict(model, testData)
(tbl - table(pred, truth = testTopic))
truth
pred 16 20
16 193 33
20 27 166
sum(diag(tbl)) / sum(tbl)
[1] 0.8568019
# 正解率
35. クラス1とクラス2のデータが50個ずつある場合
Yes No
AL AR
A
(50, 50)
(15, 32) (35, 18)
p1AL
=
15
47
p2AL
=
32
47
p1AR
=
35
53
p2AR
=
18
53
p(AL) =
47
100 p(AR) =
53
100
p1A =
50
100
p2A =
50
100
p(A) = 1
素性1 0
∆I = p(A)
2
i=1
piA(1 − piA) − p(AL)
2
i=1
piAL
(1 − piAL
) −
2
i=1
piAR
(1 − piAR
)
= 0.058
CART の学習例
36. Yes No
AL AR
A
(50, 50)
(7, 29) (43, 21)
p1A =
50
100
p2A =
50
100
p(A) = 1
素性2 0
∆I = p(A)
2
i=1
piA(1 − piA) − p(AL)
2
i=1
piAL
(1 − piAL
) −
2
i=1
piAR
(1 − piAR
)
p1AL
=
7
36
p2AL
=
29
36
p1AR
=
43
64
p2AR
=
21
64
p(AL) =
36
100 p(AR) =
64
100
= 0.105 こちらの分割方法の方が不純度の減少量が大きい(良い分割方法)
CART の学習例
クラス1とクラス2のデータが50個ずつある場合
37. 1-SE ルール
1 2 3 4 5 6
Yes No
Yes No
C1
C2
A0
A1
Yes No
Yes No
A2
A3 A4
A5C2
葉ノードの数
CVエラー
クロスバリデーション (CV) エラーとその標準偏差を基準に枝刈り
CVエラーの最小値
枝刈りすることで過学習を抑制
38. 1 2 3 4 5 6
Yes No
Yes No
C1
C2
A0
A1
Yes No
Yes No
A2
A3 A4
A5C2
CVエラーの最小値+標準偏差
クロスバリデーション (CV) エラーとその標準偏差を基準に枝刈り
葉ノードの数
CVエラー
枝刈りすることで過学習を抑制
1-SE ルール
39. 1 2 3 4 5 6
Yes No
Yes No
C1
C2
A0
A1
Yes No
Yes No
A2
A3 A4
A5C2
CVエラーの最小値+標準偏差を最初に下回る点
クロスバリデーション (CV) エラーとその標準偏差を基準に枝刈り
葉ノードの数
CVエラー
枝刈りすることで過学習を抑制
1-SE ルール
40. 1 2 3 4 5 6
Yes No
Yes No
C1
C2
A0
A1
Yes No
Yes No
A3 A4
A5C2
枝刈り C1
クロスバリデーション (CV) エラーとその標準偏差を基準に枝刈り
葉ノードの数
CVエラー
枝刈りすることで過学習を抑制
1-SE ルール
41. R で決定木
library(mvpart)
model - rpart(topic ~ .,
+ data.frame(trainData, topic = trainTopic))
pred - predict(model, data.frame(testData),
+ type = class)
(tbl - table(pred, truth = testTopic))
truth
pred 16 20
16 88 6
20 132 193
sum(diag(tbl)) / sum(tbl)
[1] 0.6706444
43. 最大エントロピー (ME) モデル
P(y|x) =
1
Z(x)
exp
i
λifi(x, y)
=
1
Z(x)
exp
λT
f(x, y)
Z(x) =
y∈Y
exp
λT
f(x, y)
(規格化定数)
経験的分布の特性を満たしつつ
エントロピーを最大にするモデル
• 柔軟に素性を設定することが可能
• 出力が確率
cf. 確率的言語モデル 6章
44. 素性関数
fb,s(x, y) =
1 if b(x) is true and y = s
0 otherwise
素性の有無を表す2値関数
• e.g.
文書のクラスが class1 で最初が数字で始まれば1,そうでなければ0
• 単語文書行列を扱う場合は「コーパスの語彙数」x 「クラス数」個の素
性関数が存在し、出現頻度などを返す関数
fbegins−with−number,class1
45. ME モデルの学習
対数尤度を最大化するパラメータを求める
• 解探索アルゴリズム
‣ L-BFGS(省メモリな準ニュートン法)
‣ GIS (Generalized Iterative Scaling)
• L1、L2 正則化で過学習を防ぐことも
‣ L2 正則化をする場合の目的関数は次のとおり
L(P|λ) =
(xi,yi)
log P(yi|xi)
L(P|λ) =
(xi,yi)
log P(yi|xi) −
1
2σ2
||λ||2
← 凸関数
46. R で ME モデル
library(maxent)
model - maxent(trainData, trainTopic)
pred - predict(model, testData)[, labels]
(tbl - table(pred, truth = testTopic))
truth
pred 16 20
16 190 36
20 30 163
sum(diag(tbl)) / sum(tbl)
[1] 0.8424821
51. 入力 特徴ベクトル カーネル多変量解析
入力空間 特徴空間入力空間
x f(x) =
n
i=1
αik
x(i)
, x)
= wT
φ(x)
(カーネル関数)
k
x(i)
, x
= φ(x(i)
)T
φ(x)
k
カーネル関数が高次元空間での計算を隠 (カーネルトリック)
カーネル法の概要
52. カーネル関数
• 線形カーネル
‣ 現在の特徴空間で SVM などを適用させたい時に使用
• ガウスカーネル
‣ データの特性を維持したまま無限次元空間に写像
• 多項式カーネル
‣ 素性間の相互作用も考慮した空間に写像
‣ 文字列カーネル cf. 文字列カーネルSVMによる辞書なしツイート分類
‣ 文字列を部分文字列の出現回数から成る空間に写像
cf. 自然言語処理におけるカーネル法の利用 (PDF)
カーネル関数によって写像する特徴空間は異なる
k(x, x
) = xT
x
k(x, x
) = exp(−βx − x
2
)
k(x, x
) = (xT
x
+ c)p
53. SVM の学習
dカーネル空間で2クラス間のマージン を最大化するように学習
‣ ソフトマージン最大化
‣ 誤分類されるものにはペナルティを設けることで誤分類を許容
‣ 凸二次計画問題に帰着できる(SMO などで解く)
||w||2
= αT
Kα kij = k(xj, xi)K = (kij), ,
カーネル関数
min
ξ,α
1
2
||w||2
+ C
n
i
ξi
Subject to ∀
i : yif(x) ≥ 1 − ξi
サポートベクトル
f(x) =
xi∈SV
αik(xi, x)
54. R で SVM
library(kernlab)
model - ksvm(trainData, trainTopic,
+ kernel = vanilladot, kpar = list(),
+ scaled = FALSE)
pred - predict(model, testData)
(tbl - table(pred, truth = testTopic))
truth
pred 16 20
16 184 28
20 36 171
sum(diag(tbl)) / sum(tbl)
[1] 0.8472554
58. やれなかったこと
• LSI cf. 潜在的意味インデキシング(LSI)徹底入門 - あらびき日記
• LDA(topicmodels パッケージ)
• 文書クラスタリング cf. Rで学ぶクラスタ解析
‣ 階層的クラスタリング(hclust 関数)
‣ k-means(kmeans 関数)
• 系列ラベリング cf. HMM, MEMM, CRF まとめ - あらびき日記
‣ HMM
‣ MEMM
• データの前処理
‣ 文書中の URL の除去(置換)
‣ Unicode 正規化 cf. abicky/RUnicode · GitHub
• KNB コーパスを使ってごにょごにょ cf. KNB corpus parser for R