Python 实现Jaccard 相似度 计算排序

基本原理

Jaccard 的核心就是。交集/并集。

公式为 Jaccard(a,b) =. | F(a) ^ F(b)| / |F(a) U F(b)||

如何理解这个 指标呢 ? 比如说 我和 我朋友都喜欢 听歌, 我们在 网易云音乐听歌,我听过的歌 和 他听过的歌 类似,那么我们这两个 用户就 非常相似。 可以 通过 jaccard 来根据我们的听歌的记录的交集和并集来计算相似度。

如果我和 我的朋友 听过的歌完全一样 ,那么 fa = fb , jaccard 为1。如果我们之间没有共同的播放记录,那么 交集为0,相似度就为零。

工程实现

Jaccard的a和b实际上就是不同 document 的 某一个 相同字段, 可以是 文本, 也可以是 id ,最后通过 F(a)来构建 集合特征。

在我的例子中,我用的是 文本的分词特征。如果 a 和b两段文本有 很大的比例是 共同的关键词,那么a和b很相似

代码

def jaccard(a,b):
    return len(set(a).intersection(set(b))) / len(set(a).union(set(b)))

def get_common_word_number(query, docs):
    #return [  len(set(query).intersection(set(d))  ) for d in docs]
    return [ jaccard(query,d) for d in docs]

def rank_feature(id2doc, query_id, eng_field, sub_data):
    query = id2doc[query_id][eng_field]
    docs = [id2doc[u][eng_field] for u in sub_data]
    if 'skill' in eng_field:
        scores = get_common_word_number(query, docs)
    elif 'vec' in eng_field:
        scores = get_similarity(query, docs)
    data = [(id, s) for id, s in zip(sub_data, scores)]
    data = sorted(data, key=lambda x: x[-1], reverse=True)
    return data

其中 eng field 是 特征 a 的字段名, sub data是 整个 document 列表, query id 是 要查询的document id, id2doc 是 一个 字典, key 是 doc id,  value 是 doc 本体。

你可能感兴趣的:(NLP,推荐系统,相似度,推荐系统,排序算法,无监督)