株式会社スマレジの開発部でスマレジのサーバサイドを作っています

チケットの見える化にチャレンジしてみる(2-3: 準備編 文書ベクトル〜コサイン類似度)

こんばんは!株式会社スマレジ のmasaです。

4連休はいかがお過ごしでしたか? masaは前後にお休みをいただけたので、古い友人にあったりして、久しぶりにゆっくり過ごせました。

さて今回は、計量テキスト分析でとてもよく使われる尺度をご紹介します。 これも形態素解析と同じく、今回のredmineチケットの見える化で利用します。 ただ、今日紹介するのは前提知識で、これをベースにした高次の尺度を実際は使用します。

文書ベクトル

前回、形態素解析を使うことで欲しい単語を抽出することができることを確認しました。 次は、抽出した単語たちを使って、二つの文書が似ているかどうかを比較することを考えます。

二つの文書A,Bがあったとします。この時、それぞれの文書から抽出した単語リストのことを「文書ベクトル」と呼びます。 ベクトルといえば、高校の数学や物理で「量(スカラー)に方向を持ったもの」と習ったかと思います。 例えば、xy平面上の原点を始点とし、(x,y)=(1,2)の点を終点とするベクトル\vec{a}


\vec{a}=(1, 2)

みたいに書いたと思います。 平面ベクトルなら1とか2などの数字が入りますが、文書ベクトルの場合は、その単語があったら1、なかったら0が入ります。 この0,1の値が単語ごとに存在するのが文書ベクトルになります。 そのため、いろいろな単語があるととても長い(=次元の大きい)ベクトルになります。

例えばAの単語リストが「りんご」「みかん」「バナナ」、Bの単語リストが「スイカ」「りんご」「いちご」だったとし、 それぞれの文書ベクトルを\vec{a},\vec{b}とすると、


\vec{a}(りんご,みかん,バナナ,スイカ,いちご)=(1,1,1,0,0) \\
\vec{b}(りんご,みかん,バナナ,スイカ,いちご)=(1,0,0,1,1) \\

というふうになります。 (これは例えで記載しているもので、記述方法は正しくはないです。専門書を見ると別の書き方をしていますのでご注意ください。)

コサイン類似度

サイン・コサイン・タンジェント、今聴くと懐かしい気持ちになる高校時代に習った三角比を実はここで使います。 コサイン類似度はその名の通り、文書の比較として、コサイン(余弦)の値を使用するものです。

さっき説明した文書ベクトルが2本あれば、二つのベクトルが角度を作るので、その角度θのコサインを求めます。

で、高校の数1では直角三角形の底辺/斜辺からcos(θ)を求めたと思いますが、 ここではベクトルの単元で出てきた方法でcos(θ)を出します。(実はこっちがcos(θ)の定義だったりします)


\cos{\theta}=\frac{\vec{a} \cdot \vec{b}}{ab}

ここの分母の a,b \vec{a},\vec{b}の大きさです。大きさはベクトルの各成分を二乗して全部足して平方根を取ったものですが、 文書ベクトルの場合は成分が0 or 1なので、例えば aであれば


a=\sqrt{文書Aで出現した単語の種類の合計} \\
=\sqrt{1+1+1+0+0} \\
=\sqrt{3}

となります。

また、分子はベクトルの内積です。これは文書ベクトルの場合だと、ダブっている単語の種類の合計になります。 今回は「りんご」だけがダブっているので


\vec{a} \cdot \vec{b} = 1

となります。

そのためコサイン類似度は


\cos{\theta}=\frac{1}{\sqrt{3} \sqrt{3}}
= \frac{1}{3}

となりました。

コサイン類似度の分子はダブっている単語の合計になるので、ダブっている数が多ければ多いほど、コサイン類似度も大きくなります。 また、文書ベクトルが0,1しか取らないため、分母、分子ともにマイナスになることはありません。最低値は一切被りがない場合なので、0になり、 最高値は全てダブった場合で1になります。なぜ全てダブった場合が1になるのかというと、分母が全部ダブっているので、出現する単語の種類数になり、分子もそれぞれのベクトルが出現する単語の種類数の平方根になるためです。

要は、1に近いほど、単語のダブりが多いということです。つまり1に近いほど文書同士が似ている可能性が高くなるわけです。

次回はpythonでコサイン類似度を計算するコードを書いてみます。