在看《集体智慧编程》的时候跟着书顺手写的

  1. 欧几里得距离
    # 返回person1 与 person2 基于欧几里得距离的相似度评价
    # sum_of squares = 所有 p1 与 p2 共同评价的物品的分数差的平方之和ß
    # 即在 "p1 与 p2 共同评价商品数量"维度 的空间中的欧几里得距离ß
    def sim_distance(prefs, person1, person2):
        si = {}
        for item in prefs[person1]:
            if item in prefs[person2]:
                si[item] = 1
    
        if len(si) == 0:
            return 0
    
        sum_of_squares = sum(
            [pow(prefs[person1][item] - prefs[person2][item], 2) for item in prefs[person1] if item in prefs[person2]])
    
        return 1 / (1 + sqrt(sum_of_squares))
  2. 曼哈顿距离
    # 曼哈顿距离
    def sim_manhattan(prefs, person1, person2):
        si = {}
        for item in prefs[person1]:
            if item in prefs[person2]:
                si[item] = 1
    
        if len(si) == 0:
            return 0
    
        sum_of_manhattan = sum(
            [abs(prefs[person1][item] - prefs[person2][item]) for item in prefs[person1] if item in prefs[person2]])
    
        return 1 / (1 + sum_of_manhattan)
  3. 皮尔逊(Pearson)相关度
    # 基于皮尔逊相关度评价
    def sim_pearson(prefs, person1, person2):
        si = {}
        for item in prefs[person1]:
            if item in prefs[person2]:
                si[item] = 1
    
        n = len(si)
        if n == 0:
            return 0
        # 对所有偏好求和
        sum1 = sum(prefs[person1][it] for it in si)
        sum2 = sum(prefs[person2][it] for it in si)
    
        # 求平方和
        sum1Sq = sum([pow(prefs[person1][it], 2) for it in si])
        sum2Sq = sum([pow(prefs[person2][it], 2) for it in si])
    
        # 乘积之和
        pSum = sum([prefs[person1][it] * prefs[person2][it] for it in si])
    
        # 计算评价值
        num = pSum - (sum1 * sum2 / n)
        den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
        if den == 0:
            return 0
    
        r = num / den
        return r
  4. Tanimoto相关度
    未验证正确性= =有错误请告知

    # Tanimoto相似度(广义Jaccard系数)
    # T(A,B) = (A * B) / (Sqrt(A^2) + Sqrt(B^2) - A * B)
    def sim_tanimoto(prefs, person1, person2):
        si = {}
        for item in prefs[person1]:
            if item in prefs[person2]:
                si[item] = 1
    
        n = len(si)
        if n == 0:
            return 0
    
        # 计算(A * B)
        pSum = sum([prefs[person1][it] * prefs[person2][it] for it in si])
    
        # 计算 Sqrt。。
        sum1Sq = sum([pow(prefs[person1][it], 2) for it in si])
        sum2Sq = sum([pow(prefs[person2][it], 2) for it in si])
    
        # 计算相关度
        t = pSum / (sum1Sq + sum2Sq - pSum)
        return t

     

以上均适用于如下类型的数据集:

critics = {
    '用户A': {
        '集体智慧编程': 2.5,
        '机器学习': 3.5,
        '数据之美': 3.0,
        '数据挖掘导论': 3.5,
        '深入浅出数据挖掘': 2.5,
        '数据挖掘实战': 3.0
    },
    '用户B': {
        '集体智慧编程': 3.0,
        '机器学习': 3.5,
        '数据之美': 1.5,
        '数据挖掘导论': 5.0,
        '深入浅出数据挖掘': 3.5,
        '数据挖掘实战': 3.0
    },
    '用户C': {
        '集体智慧编程': 2.5,
        '机器学习': 3.0,
        '数据挖掘导论': 3.5,
        '深入浅出数据挖掘': 4.0
    },
    '用户D': {
        '集体智慧编程': 3.5,
        '数据之美': 3.0,
        '数据挖掘导论': 4.0,
        '深入浅出数据挖掘': 4.0,
        '数据挖掘实战': 2.5
    },
    '用户E': {
        '集体智慧编程': 3.0,
        '机器学习': 4.0,
        '数据之美': 2.0,
        '数据挖掘导论': 3.0,
        '深入浅出数据挖掘': 3.0,
        '数据挖掘实战': 2.5
    },
    '用户F': {
        '集体智慧编程': 3.0,
        '机器学习': 4.0,
        '数据挖掘导论': 5.0,
        '深入浅出数据挖掘': 3.0,
        '数据挖掘实战': 2.0
    },
    '用户G': {
        '集体智慧编程': 4.5,
        '数据挖掘导论': 4.0,
        '深入浅出数据挖掘': 1.0
    },
}