clip-as-service
clip-as-service copied to clipboard
获取词向量并进行相似度计算
我做的实验是对中文文本分词后获取每个词语的词向量,然后拿这个词向量去进行相似度计算(本来是想直接进行聚类的)。 我用的模型是google的中文模型 chinese_L-12_H-768_A-12 相似度计算是这么算的: def cos_sim(vector_a, vector_b): vector_a = np.mat(vector_a) vector_b = np.mat(vector_b) num = float(vector_a * vector_b.T) denom = np.linalg.norm(vector_a) * np.linalg.norm(vector_b) cos = num / denom sim = 0.5 + 0.5 * cos return sim
获取词向量,计算第一句中的“苹果”的词向量与第二句中所有词的相似性: vec1 = bc.encode([['我', '喜欢', '吃', '苹果']], is_tokenized=True) vec2 = bc.encode([['我', '用', '苹果', '手机']], is_tokenized=True)
for i in range(4):
print(cos_sim(vec1[0][4], vec2[0][i+1]))
这个是结果: 0.8909359757911572 0.9085327476504197 0.9434556624695274 0.9522615639582642
即使看相对相似度,结果也不理想,是我代码哪里有问题,还是什么原因! 谢谢!
这个问题在句子长度有所增加以后,结果好像好了一些。 vec1 = bc.encode([['我', '喜欢', '吃', '苹果']], is_tokenized=True) vec2 = bc.encode([['我', '用', '苹果', '手机', "妹妹", "在吃", "橘子"]], is_tokenized=True)
for i in range(7): print(cos_sim(vec1[0][4], vec2[0][i+1]))
这是结果: 0.8890991046993251 0.901118192389121 0.93790840387366 0.9325583833568518 0.9351127618819679 0.9261931160690539 0.9493794565797229
这时候可以看到,与第一句中的苹果最相似的是第二句中的橘子,其次是第二句中的苹果。但是其他不太相关的词语,仍然具有较高的相似性。即使修改相似系数,直接返回cos的结果,相似性的结果基本都在0.85以上。
bert的pre-trained的模型生成的原始word embedding/sentence embedding是不适合做cosine similarity的。具体参见以下链接:
https://github.com/UKPLab/sentence-transformers/issues/80
“Cosine-Similarity / Manhatten-Distance / Euclidean-Distance treat all dimension equally, with the same weight. I.e., to get well working sentence embeddings for unsupervised tasks, it is important that all dimensions "make sense" and have the "same scale".
BERT was not optimized for this, that all output-dimensions must contribute equally. For supervised tasks, the classifier learns which dimension contribute and what the "scale" of those are. But for unsupervised tasks, we sadly don't have this luxury.”