tanimoto係数のメモ

オブジェクト間の類似度を測る方法の一つにtanimoto係数というのがあります。wikipediaには集合間の類似度を求めるとの説明がありますが、オブジェクトはプロパティの集合なので別に問題はありませんね。

定義はwikipediaの通りなのですが、日本語では無いので書いておきます。
[tex]
\begin{eqnarray}
T(A,B)=\frac{ A\cdot B }{ |A|^2+|B|^2-A\cdot B}
\end{eqnarray}
[/tex]
この値はベクトルAとBが完全に一致した場合は1、全く一致しない場合は0になるので正規化等する必要もなく使い易いですね。もちろん1に近いほど類似度は高くなります。

pythonで簡易的に書いてみました。入力は辞書限定ですが簡単です。

#!/usr/bin/python
# -*- coding: utf-8 -*-

def tanimoto_ce(set_a, set_b):
  product = 0.0
  for item in set_a:
    if item in set_b:
      product += set_a[item] * set_b[item]
  a_sq = sum([pow(set_a[item], 2) for item in set_a])
  b_sq = sum([pow(set_b[item], 2) for item in set_b])
  return float(product / (a_sq + b_sq - product))
        
A = { 'as3':2.0,    'python':2.0, 'perl':2.5, 'php':3.0, 'c++':4.5, 'java':2.5 }
B = { 'scheme':4.0, 'python':3.0, 'perl':4.0, 'c++':5.0 }
C = { 'java':3.5,   'as3':3.5,    'c++':2.0,  'perl':1.0 }

print tanimoto_ce(A, B)   # 0.498381877023
print tanimoto_ce(B, C)   # 0.171779141104
print tanimoto_ce(C, A)   # 0.524038461538

まだ性質等は把握していないので色々と実験してみようと思います。

Leave a Reply

Your email address will not be published. Required fields are marked *