PythonでJaccard係数を求める(Dice係数,Simpson係数の簡単な説明あり)

こんにちは、@Yoshimiです。

自然言語処理関連に携われば、120%ベクトルというキーワードを耳にします。文字をベクトル化し、その距離を計算してうんぬんカンヌンするというものです。中身としては、文書、文字列、集合等について類似度を計算しています。その集合同士の類似度を計算する際によく利用される3つの係数をご紹介します。

  • Jaccard係数
  • Dice係数
  • Simpson係数

私の業務では、Jaccard係数がメインなので、Jaccard係数に重きを置き、その他2つの係数はサクッとした説明にします。

Jaccard係数

Jaccard係数は、ある集合Aと別の集合BについてのJaccard係数J(A,B)は,以下の式で定義されます。

$$J(A,B)=\frac{|A \cap B|}{|A \cup B|}$$

例えば、集合A = [1, 2, 3, 4]、 集合B = [3, 4, 8, 9] があったとします。\(|A \cap B|=2\)、\(|A \cup B|=6\) なので、Jaccard係数は \(\frac{2}{6}\)となります。

上記計算式からもわかる通り、2つの集合に含まれている要素のうち共通要素が占める割合を表しております。係数は0から1の間の値となることがわかります。Jaccard係数が大きいほど(1に近いほど)A と B は似ている(よく似ている)といえます。

Pythonで実装してみる

[1 2 3 4] & [2 3 5 7] : 0.3333333333333333
[1 2 3 4] & [2 4 6] : 0.4
[2 3 5 7] & [2 4 6] : 0.16666666666666666

他の求め方

0.42857142857142855

Dice係数

Jaccard係数の定義式の分母はAにもBにも含まれている要素の数でしたが、これを「Aの要素数とBの要素数の共通要素数の割合平均」に変えるとDice係数となります。Dice係数が大きいほど2つの集合の類似度は高い(よく似ている)といえます。

ある集合Aと別の集合BについてのDice係数DSC(A,B)は,以下の式で定義されます。
$$DSC(A,B)=\frac{2|A \cap B|}{|A|+|B|}$$

例えば、集合A = [1, 2, 3, 4]、 集合B = [3, 4, 8, 9] があったとします。
\(|A| = 4 \)、\(|B| = 4\)、\(|A \cap B|=2\)なので、Dice係数は \(\frac{2\times 2}{4+4}=\frac{4}{8}\)となります。

Simpson係数

Jaccard係数の定義式の分母はAにもBにも含まれている要素の数でしたが、これを「Aの要素数とBの要素数のうちの小さい方」に変えるとSimpson係数になります。Simpson係数が大きいほど2つの集合の類似度は高い(よく似ている)といえます。

$$overlap(A,B)=\frac{|A \cap B|}{\min\{|A|,|B|\}}$$

例えば、集合A = [1, 2, 3, 4]、 集合B = [3, 4, 8, 9] があったとします。
\(|A| = 4 \)、\(|B| = 4\)、\(|A \cap B|=2\)なので、Simpson係数は \(\frac{2}{4}=\frac{2}{4}\)となります。

最後に

集合の類似度ということで「Jaccard係数」「Dice係数」「Simpson係数」を紹介しました。3つの係数にはある性質があります。

  • Jaccard係数、Dice係数、Simpson係数は、いずれも 0 以上 1 以下
  • AとBで共通部分を持たない時、3つの係数は全て0になります。逆に全て共通であれば係数は1になる

Dice係数、Simpson係数の実装はまたの機会にアップしたいと思います。

Jaccard係数で私が参考にさせてもらった資料はこちらです。

参考:

ABOUTこの記事をかいた人

Yoshimi

大学卒業して、キラキラしていたのでIT業界にはいりましたが、中身はブラックでした!!だから、投資技術を磨いて早くリタイヤしたいです。株価、Python、機械学習をもうもう勉強中です。