- ラベル付きデータが入手できない状況を考える
- Q&Aサイトを運営する場面。今見ているページ内容と関連する情報を提示したい。
- 文書間の類似度を素早く算出することで実現する。クラスタリングを使う。
1文字の挿入・削除・置換によって、一方の文字列をもう一方の文字列に変形するのに必要な手順の最小回数として定義される
https://ja.m.wikipedia.org/wiki/レーベンシュタイン距離
- machine と mchiene の距離は2
- 長さmとnの文書間の距離を計算するアルゴリズムのオーダーは*O(mn)*になる
- 計算コストが高い
- 単語の順序についてロバストでない(影響を受けやすい)
文書内に単語が含まれるかどうかだけに着目したモデル。単語の並び順は考慮しない。文書の各単語に対して出現回数をカウントしてベクトルとして表現する。これは、*ベクトル化(vectorization)と呼ばれ、このベクトルを特徴ベクトル(feature vectors)*と呼ぶ。
単語の種類が、
(disk, format, now, hard, my, problems, to)
のとき、“Hard disk format problems” の特徴ベクトルは、
(1,1,0,1,0,1,0)
となる。
ベクトル化すればユークリッド距離で比較できるようになる。 また最近傍点を見つけられる。ただし、時間がかかってしまう(これは、何故か?)
- 各文書から特徴量を抽出し、特徴ベクトルの形で保存する。
- 特徴ベクトルに対して、クラスタリングを行う。
- 投稿された質問文書に対して、クラスタを決定する。
- このクラスタに属する文書を他にいくつか集める。
bag-of-wordsは高速でロバストだが問題がないわけではない。
sklearn
のCountVectorizer
を使う。
import scipy as sp
def dist_raw(v1, v2):
delta = v1 - v2
return sp.linalg.norm(delta.toarray())
ユークリッド距離を計算する関数。これを使って文書間の距離を計算し、最も近いものが類似度が高いと言える。
単語の出現回数からなるベクトルではなく、正規化したベクトルを返すようにする。
def dist_norm(v1, v2):
v1_normalized = v1 / sp.linalg.norm(v1.toarray())
v2_normalized = v2 / sp.linalg.norm(v2.toarray())
delta = v1_normalized / v2_normalized
return sp.linalg.norm(delta.toarray())
stop word
を取り除く。most
とか分野に関係なく現れる単語のこと。
image
とimages
が別な単語として扱われている。語幹に変換する処理のことをステミングという。
TF-IDF(term frequency - inverse document frequency)
d: 文書 t: 単語 n(i,j): 単語t(i)の文書d(j)における出現回数
TF(i, j) = n(i,j) / Σ n(k,j) IDF(i) = log( |D| / |{d: d∋t(i)}|) https://ja.wikipedia.org/wiki/Tf-idf
特定の文書だけで現れやすい単語に特徴量として大きい値を設定できるようになる。
テキストデータの前処理
- 単語の関連性を考慮していない
- 否定的な意味を正しく考慮していない。bi-gramやtri-gramをカウントすることで対応できる。
- タイプミスに対応できない
- フラットクラスタリング (flat clustering)
- 階層的クラスタリング (hierarchical clustering)
フラットクラスタリングでは予めクラスタ数を決める必要がある。階層的クラスタリングではクラスタ数を指定する必要はない。
フラットクラスタリング。よく用いられる。
- クラスタの数だけ任意に選び出し、クラスタの中心点とする
- 選ばれなかったデータも最も近い中心点をもつクラスタとする。
- 各クラスタで中心点を更新する。クラスタに属するデータの平均を中心とする。
- 中心点が動かなくなる(閾値以下の移動量になる)まで中心点の更新を繰り返す。
中心点が動く様子。
- 20newsgroupというデータセットを使ってテスト
- 正解となるラベルがすでにわかっている
- 現実のデータにはノイズが含まれる
- UnicodeDecodeError: 不適切な文字が含まれているなど
- 新しい文書が来たときにラベル予測をする
- まず、文書をベクトル化してから予測する
予測ができたら、同じクラスタに所属する文書との類似度を評価する
comp.graphics
に所属する決め手
を見つけることができるか?
- ストップワードの削除
- TF/IDFの計算
識別性の高い単語を見つけるのは難しい
調整するパラメータや手法はいろいろあるが、「より良い」とはどういうことかを定義しておく必要がある。 scikit
では sklearn.metrics
というパッケージがありクラスタリングの性能を計測するための評価関数が含まれている。