【实验目的】
【实验原理】
【实验环境】
【实验内容】
【实验步骤】
import numpy as np
#(1)数据输入。
users = ["贝贝", "晶晶", "欢欢", "迎迎", "妮妮"]
movies = ["战狼2", "哪吒之魔童转世", "流浪地球", "红海行动", "唐人街探案2", "美人鱼", "我和我的祖国"]
UsMoList=[
[1, 1, 1, 0, 1, 0, 0],
[0, 1, 1, 0, 0, 1, 0],
[1, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0],
[1, 1, 0, 1, 0, 1, 1]]
#(2)将行转为列
def RowConverCol():
return np.array(UsMoList).transpose().tolist()
#(3)使用欧氏距离计算两个电影之间的相似度。
def euc_mv_sim(movieFirst: list, movieSecond:list):
return np.sqrt(((np.array(movieFirst) - np.array(movieSecond)) ** 2).sum())
#(4)计算所有电影之间的相似度。
def allmv_sim():
resDic = {}
tempList = RowConverCol()
for i in range(0, len(tempList)):
for j in range(i+1, len(tempList)):
resDic[str(i) + '-' + str(j)] = euc_mv_sim(tempList[i], tempList[j])
return resDic
#(5)计算要推荐哪些电影。
def comput_Rec_mo(username: str) -> list:
temp = {}
mo_sim_dic = allmv_sim()
userindex = users.index(username)
TargetUsermovieList = UsMoList[userindex]
for i in range(0, len(TargetUsermovieList)):
for j in range(i+1, len(TargetUsermovieList)):
if TargetUsermovieList[i] == 1 and TargetUsermovieList[j] == 0 and (mo_sim_dic.get(str(i) + '-' + str(j)) != None or mo_sim_dic.get(str(j) + '-' + str(i)) != None):
sim = mo_sim_dic.get(str(i) + '-' + str(j)) if(mo_sim_dic.get(str(i) + '-' + str(j)) != None) else mo_sim_dic.get(str(j) + '-' + str(i))
temp[j] = sim
elif TargetUsermovieList[i] == 0 and TargetUsermovieList[j] == 1 and (mo_sim_dic.get(str(i) + '-' + str(j)) != None or mo_sim_dic.get(str(j) + '-' + str(i)) != None):
sim = mo_sim_dic.get(str(i) + '-' + str(j)) if (mo_sim_dic.get(str(i) + '-' + str(j)) != None) else mo_sim_dic.get(str(j) + '-' + str(i))
temp[i] = sim
temp = sorted(temp.items(), key=lambda d:d[1])
#temp = sorted(temp.items())
print("推荐列表:",temp)
recommendlist = [movies[i] for i,v in temp]
print("电影推荐:", recommendlist)
return recommendlist
print(allmv_sim())
comput_Rec_mo("晶晶")
comput_Rec_mo("欢欢")
# -*- coding=utf-8 -*-
import math
from operator import *
#(1)将原始数据存储到一个用户字典dic中。
dic = {'贝贝': ('战狼2', '哪吒之魔童降世', '红海行动'), '晶晶': ('战狼2', '流浪地球'), '欢欢': ('哪吒之魔童降世', '唐人街探案2'), '迎迎': ('流浪地球', '红海行动', '唐人街探案2')}
#(2)将dic字典转成商品-用户字典。
#计算用户兴趣相似度
def userSim(dicc):
#把用户-商品字典转成商品-用户字典
item_user=dict()
for u,items in dicc.items():
for i in items:
if i not in item_user.keys():
item_user[i]=set() #i键所对应的值是一个集合(不重复)。
item_user[i].add(u)
C=dict()#真实数据集为数字编号,但这里是字符,这里还用字典。
N=dict()
for item,users in item_user.items():
for u in users:
if u not in N.keys():
N[u]=0
N[u]+=1 #每个商品下用户出现一次就加一次,就是计算每个用户一共购买的商品个数。
for v in users:
if u==v:
continue
if (u,v) not in C.keys():#同上,没有初始值不能+=
C[u,v]=0
C[u,v]+=1
#(3)到这里倒排阵就建立好了,下面是计算相似度。
W=dict()
for co_user,cuv in C.items():
W[co_user]=cuv / math.sqrt(N[co_user[0]]*N[co_user[1]])
return W
#(4)找到K个相关用户以及对应兴趣相似度,按兴趣相似度从大到小排列。
def userRec(user,dicc,W2,K):
rvi=1 #这里都是1,实际中可能每个用户就不一样了。就像每个人都喜欢beautiful girl,但有的喜欢可爱的多一些,有的喜欢御姐多一些。
rank=dict()
related_user=[]
interacted_items=dicc[user]
for co_user,item in W2.items():
if co_user[0]==user:
related_user.append((co_user[1],item))#先建立一个和待推荐用户兴趣相关的所有的用户列表。
for v,wuv in sorted(related_user,key=itemgetter(1),reverse=True)[0:K]:
for i in dicc[v]:
if i in interacted_items:
continue
if i not in rank.keys():
rank[i]=0
rank[i]+=wuv*rvi
return rank
if __name__=='__main__':
W3=userSim(dic)
Last_Rank=userRec('晶晶',dic,W3,2)
print (Last_Rank)