现在想到的方法是如下
--方法 1--
A 列表:['aa', 'bb', 'cc']
B 列表:['bb', 'cc', 'ff', 'kk']
因为'bb'和'cc'相同所以有
A:2/3
B:2/4
所以 AB 相似度等于:(2/3 + 2/4) / 2 = 0.583
假如有 C 列表:['bb']
同样与 B 列表比较,同理 BC 相似度等于:(1/4+1/1) / 2 = 0.625
然而 AB 相似度<BC 相似度却不太理想
--方法 2--
另外一个方法就是分母用元素的合计数
AB 相似度等于:(2/(3+4) + 2/(3+4)) / 2 = 0.286
BC 相似度等于:(1/(4+1)+1/(4+1)) / 2 = 0.2
结果:AB 相似度>BC 相似度
所以正确的方案应该用数学上的那些手段来实现呢?
1
youngxhui 2019-03-29 10:22:40 +08:00 via Android 1
使用余弦距离
|
2
aijam 2019-03-29 10:26:51 +08:00 1
比如 edit distance,TF/IDF
|
3
SeaRecluse 2019-03-29 10:28:03 +08:00 1
只比较两个交叉熵,多个用余弦距离
|
4
largecat 2019-03-29 10:33:23 +08:00 via Android 1
还有一个
A,B 合起来总共不重复的 5 个元素,共有 2 个,所以 2/5=40 % BC 合计不重复 4 个,共有 1 个所以 1/4=25 % |
5
cdcfishzz 2019-03-29 10:57:52 +08:00 via Android 1
方法 2 是不正确的。
假设两个完全一样的列表,预期值为 1。 (3/(3+3)+3/(3+3))/2 = 3/6≠1。 |
6
adrianyoung 2019-03-29 11:19:00 +08:00 1
可以参考一下 BLEU 的惩罚因子
能够解决你提到的方法一的问题 |
7
wkc 2019-03-29 11:25:50 +08:00 1
|
8
adrianyoung 2019-03-29 11:27:58 +08:00 1
或者两个列表直接构建一个向量空间,算余弦距离
|
9
holajamc 2019-03-29 11:38:15 +08:00 1
In [1]: a = ['a', 'b', 'c']
In [2]: b = ['a', 'b', 'd'] In [3]: def jaccard_sim(a, b): ...: return len(set(a).union(set(b)))/len(set(a).intersection(set(b))) ...: In [4]: jaccard_sim(a, b) Out[4]: 2.0 杰卡德相似性 |
10
mamahaha 2019-03-29 11:50:17 +08:00 1
很简单,并集除以交集,数值越大越不相似
|
11
binux 2019-03-29 12:07:29 +08:00 via Android 2
顺序有关=>编辑距离
顺序无关=>交集并集 最终还是取决于应用 |
12
swordspoet 2019-03-29 12:58:06 +08:00 1
|
13
no1xsyzy 2019-03-29 14:31:30 +08:00 1
首先两个分母含义不同的比值肯定不是算数平均或者平方平均
第二个其实就是调和平均的一半——不如直接使用调和平均 顺便考虑一下几何平均 |