Tanimoto相似性又称Jaccard系数,可以计算两个二进制向量(也可以计算非二进制)的相似性公式为
J=|A∩B|/|A∪B|

比如[0,1,0,1,0]与[1,1,1,0,0] 的交集为[0,1,0,0,0] 长度为1,并集为[1,1,1,1,0]长度为4,所以相似度为0.25

实现方法其实有很多,我的方法是 先将向量转化成set,比如[0,1,0,1,0]转化成set([1,3]),即第1位和第3位是1,其他的0,因为这样可以直接利用python中集合的运算符 &和|,源码见下面。当然这仅能计算二进制的,如果要扩展到非二进制的,可参看这篇文章:
http://blog.csdn.net/ns2250225/article/details/43817725

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def similarity(algorithm,feature):
''' This function can calculate the similarity of the compounds
algorithm : Tanimoto
'''
des = []
for each in feature:
eachdes=set()
for i,item in enumerate(each):
if item == 1:eachdes.add(i)
des.append(eachdes)

n=len(feature)
similar_matrix=[]
if algorithm == 'Tanimoto':
for i in range(n):
similar_matrix.append([1]*n)
for j in range(0,i):
similar_matrix[i][j]=similar_matrix[j][i]
for j in range(i+1,n):
intersection = len(des[i] & des[j])
unionset = len(des[i] | des[j])
similar_matrix[i][j]= 0 if unionset==0 else intersection * 1.0 / unionset
return similar_matrix

用Matplotlib绘制热图网上已经有不少版本,可这两篇文章:
http://ribozyme.blog.sohu.com/182128700.html
http://blog.csdn.net/rumswell/article/details/6581134

我在这里做一个综合
首先引入库 :

1
2
3
4
5
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import cm
from matplotlib import axes
import random

接着产生数据集
1
2
3
4
5
6
#generate features
feature = []
for i in range(100):
feature.append([random.choice((0,1)) for x in range(20)])
#calculate the similarity
A = np.array(similarity('Tanimoto',feature))

然后设置背景、添加子图,设置cmap形式,展现子图、显示右边的颜色栏
1
2
3
4
5
fig = plt.figure(facecolor="w")
ax1 = fig.add_subplot(111) #111表示整体布局为1行1列,此为第1副。221即2行2列此为第1副
cmap = cm.get_cmap("RdBu_r") #除了RdBu外还有很多可以选择的,具体可以help(cm)查看,_r表示reverse 还有一些可选的cm.jet, cm.winter, cm.cool, cm.hot等
im=ax1.imshow(A,cmap=cmap) #可以加interpolation="nearest" 参数 使得色块不自动羽化
cb = plt.colorbar(mappable=im)

最后可以选择保存为图片还是直接显示
1
2
plt.savefig('a.jpg')
#plt.show()

图片效果:
blog-similarity-matplotlib.jpg