现在想到的方法是如下 --方法 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 ![]() 使用余弦距离 |
![]() | 2 aijam 2019-03-29 10:26:51 +08:00 ![]() 比如 edit distance,TF/IDF |
3 SeaRecluse 2019-03-29 10:28:03 +08:00 ![]() 只比较两个交叉熵,多个用余弦距离 |
![]() | 4 largecat 2019-03-29 10:33:23 +08:00 via Android ![]() 还有一个 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 ![]() 方法 2 是不正确的。 假设两个完全一样的列表,预期值为 1。 (3/(3+3)+3/(3+3))/2 = 3/6≠1。 |
![]() | 6 adrianyoung 2019-03-29 11:19:00 +08:00 ![]() 可以参考一下 BLEU 的惩罚因子 能够解决你提到的方法一的问题 |
![]() | 7 wkc 2019-03-29 11:25:50 +08:00 ![]() |
![]() | 8 adrianyoung 2019-03-29 11:27:58 +08:00 ![]() 或者两个列表直接构建一个向量空间,算余弦距离 |
![]() | 9 holajamc 2019-03-29 11:38:15 +08:00 ![]() 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 ![]() 很简单,并集除以交集,数值越大越不相似 |
![]() | 11 binux 2019-03-29 12:07:29 +08:00 via Android ![]() 顺序有关=>编辑距离 顺序无关=>交集并集 最终还是取决于应用 |
![]() | 12 swordspoet 2019-03-29 12:58:06 +08:00 ![]() |
![]() | 13 no1xsyzy 2019-03-29 14:31:30 +08:00 ![]() 首先两个分母含义不同的比值肯定不是算数平均或者平方平均 第二个其实就是调和平均的一半不如直接使用调和平均 顺便考虑一下几何平均 |