基于物品的协同过滤算法,基于协同过滤算法

#基于物品的协同过滤算法
from math import sqrt
import operator
#构建用户-->物品的倒排
import matplotlib.pyplot as plt


def loadData(files):
    data ={};
    for line in files:
        user,score,item=line.split(",");
        data.setdefault(user,{});
        data[user][item]=score;
    print("用户:物品的倒排:" )
    print(data )
    return data
#计算
# 构造物品-->物品的共现矩阵
# 计算物品与物品的相似矩阵
def similarity(data):
    # 构造物品:物品的共现矩阵
    N={};#喜欢物品i的总人数
    C={};#喜欢物品i也喜欢物品j的人数
    for user,item in data.items():
        for i,score in item.items():
            N.setdefault(i,0);
            N[i]+=1;
            C.setdefault(i,{});
            for j,scores in item.items():
                if j not in i:
                    C[i].setdefault(j,0);
                    C[i][j]+=1;

    print("2.构造的共现矩阵:" )
    print ('N:',N);
    print ('C',C);

    #计算物品与物品的相似矩阵
    W={};
    for i,item in C.items():
        W.setdefault(i,{});
        for j,item2 in item.items():
            W[i].setdefault(j,0);
            W[i][j]=C[i][j]/sqrt(N[i]*N[j]);
    print("3.计算的相似矩阵:" )
    print(W )
    return W

#根据用户的历史记录,给用户推荐物品
def recommandList(data,W,user,k=3,N=10):
    rank={};
    for i,score in data[user].items():#获得用户user历史记录,如A用户的历史记录为{'a': '1', 'b': '1', 'd': '1'}
        for j,w in sorted(W[i].items(),key=operator.itemgetter(1),reverse=True)[0:k]:#获得与物品i相似的k个物品
            if j not in data[user].keys():#该相似的物品不在用户user的记录里
                rank.setdefault(j,0);
                rank[j]+=float(score) * w;
    print("4.推荐:" )
    print(sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:N] )
    return sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:N];
if __name__=='__main__':
    print("***基于物品的协同过滤算法的电影推荐实例实现***")
    print("1.构造数据:" )
    data ={  'UserA': {'《老炮儿》': 4.5, '《唐人街探案》': 4.5,'《星球大战》': 4.0, '《寻龙诀》': 3.5,'《神探夏洛特》': 3.0, '《小门神》': 2.5},

             'UserB': {'《老炮儿》': 4.0, '《唐人街探案》': 3.5,'《星球大战》': 4.5, '《寻龙诀》': 3.0, '《神探夏洛特》': 3.0,'《小门神》': 3.5},

             'UserC': {'《老炮儿》': 4.5, '《唐人街探案》': 4.0,                 '《寻龙诀》': 3.5, '《神探夏洛特》': 3.0},

             'UserD': {             '《唐人街探案》': 4.5, '《星球大战》': 4.0,'《寻龙诀》': 4.0, '《神探夏洛特》': 3.5,'《小门神》': 2.5},

             'UserE': {'《老炮儿》': 4.0, '《唐人街探案》': 4.0,'《星球大战》': 4.0, '《寻龙诀》': 4.5, '《神探夏洛特》': 3.0,'《小门神》': 3.0},

             'UserF': {'《老炮儿》': 4.0, '《唐人街探案》': 4.0,                 '《寻龙诀》': 3.5, '《神探夏洛特》': 3.0,'《小门神》': 3.5},

             'UserG': {              '《唐人街探案》': 4.5,                '《寻龙诀》': 4.0,             '《小门神》': 2.0}
             }

    W=similarity(data);#计算物品相似矩阵
    recommandList(data,W,'UserG',10,10);#推荐
运行结果:





#基于协同过滤算法

 

# A dictionary of movie critics and their ratings of a small#
critics = {
    'A': {'老炮儿': 3.5, '唐人街探案': 1.0},
    'B': {'老炮儿': 2.5, '唐人街探案': 3.5, '星球大战': 3.0, '寻龙诀': 3.5,
          '神探夏洛克': 2.5, '小门神': 3.0},
    'C': {'老炮儿': 3.0, '唐人街探案': 3.5, '星球大战': 1.5, '寻龙诀': 5.0,
          '神探夏洛克': 3.0, '小门神': 3.5},
    'D': {'老炮儿': 2.5, '唐人街探案': 3.5, '寻龙诀': 3.5, '神探夏洛克': 4.0},
    'E': {'老炮儿': 3.5, '唐人街探案': 2.0, '星球大战': 4.5, '神探夏洛克': 3.5,
          '小门神': 2.0},
    'F': {'老炮儿': 3.0, '唐人街探案': 4.0, '星球大战': 2.0, '寻龙诀': 3.0,
          '神探夏洛克': 3.0, '小门神': 2.0},
    'G': {'老炮儿': 4.5, '唐人街探案': 1.5, '星球大战': 3.0, '寻龙诀': 5.0,
          '神探夏洛克': 3.5}
}
# print(critics['B']['星球大战'])=3.0
from math import sqrt


def sim_distance(prefs, person1, person2):
    si = {}
    for item in prefs[person1]:
        if item in prefs[person2]: si[item] = 1
    # 如果两者没有共同之处,则返回0
    if len(si) == 0: return 0
    # sum函数参数:sum(iterable[, start]),其中iterable为可迭代对象,可以是list、tuple或者dictionary等
    # "item for item in a if item in b" 这种表达式叫作列表推导式,是在一组字符串或者一组对象上执行一条相同操作的简洁写法!
    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))


# print(sim_distance(critics, 'A', 'B'))


# Gets recommendations for a person by using a weighted average
# of every other user's rankings
def getRecommendations(prefs, person, similarity=sim_distance):
    totals = {}
    simSums = {}
    for other in prefs:
        # don't compare me to myself
        if other == person: continue
        sim = similarity(prefs, person, other)
        # ignore scores of zero or lower
        if sim <= 0: continue
        for item in prefs[other]:
            # only score movies I haven't seen yet
            if item not in prefs[person] or prefs[person][item] == 0:
                # Similarity * Score
                totals.setdefault(item, 0)
                totals[item] += prefs[other][item] * sim
                # Sum of similarities
                simSums.setdefault(item, 0)
                simSums[item] += sim
    # Create the normalized list
    rankings = [(total / simSums[item], item) for item, total in totals.items()]
    # Return the sorted list
    rankings.sort()
    rankings.reverse()
    return rankings


print(getRecommendations(critics, 'A'))

运行结果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值