使用基于用户的协同过滤算法进行电影推荐
1、简单构建数据
构建一个用户浏览记录表 主要为4个属性,编号、用户编号、新闻编号和新闻喜好程度
其中新闻喜好程度是根据用户浏览、评论、点赞、收藏等操作进行判定的,操作越多分数越高
2、数据格式化
将数据格式化为字典形式,便于解析
# 连接数据库
try:
db = pymysql.connect(host="127.0.0.1", user="root",
passwd="tttt",
db="newsproject",
charset='utf8')
except:
print("could not connect to mysql server")
# 获取某个用户的阅读记录 ((1, 1, 3), (1, 2, 2), (1, 3, 3), (1, 4, 1))
def getuserlog(id):
user_id = str(id)
cursor = db.cursor()
sql = "SELECT user_id,news_id,prefer_degree FROM newslog WHERE user_id = " + user_id
cursor.execute(sql)
results = cursor.fetchall()
db.close()
return results
# 获取用户总数
def getMaxId():
cursor = db.cursor()
sql = "SELECT MAX(user_id) FROM newslog"
cursor.execute(sql)
result = cursor.fetchone()
db.close()
return result[0]
# 获取一个用户的浏览记录 新闻:评分 {'1': '3', '4': '1', '10': '1', '9': '1'}
def format1(result):
data={}
for i in range(0, len(result)):
data[str(result[i][1])] = str(result[i][2])
return data
# 将所有用户的记录格式化
def format2(n):
res = {}
for i in range(n):
data = format1(getuserlog(i+1))
res[str(i+1)] = data;
return res
3、计算相似度
使用欧式距离计算相似度
def Euclid(user1, user2,data):
# 取出两位用户看过的新闻和评分
user1_data = data[user1]
user2_data = data[user2]
distance = 0
# 找到两位用户都看过的新闻,并计算欧式距离
for key in user1_data.keys():
if key in user2_data.keys():
# 注意,distance越大表示两者越相似
distance += pow(float(user1_data[key]) - float(user2_data[key]), 2)
return 1 / (1 + sqrt(distance)) # 这里返回值越小,相似度越大
#计算某个用户与其他用户的相似度
def top_simliar(userID,data):
res = []
for userid in data.keys():
#排除与自己计算相似度
if not userid == userID:
simliar = Euclid(userID,userid,data)
res.append((userid,simliar))
res.sort(key=lambda val:val[1])
return res
4、生成新闻推荐表
def recommend(user,data):
#相似度最高的用户
top_sim_user = top_simliar(user,data)[0][0]
#相似度最高的用户的阅读记录
items = data[top_sim_user]
recommendations = []
#筛选出该用户未阅读的新闻并添加到列表中
for item in items.keys():
if item not in data[user].keys():
recommendations.append((item,items[item]))
recommendations.sort(key=lambda val:val[1],reverse=True)#按照评分排序
return recommendations
def recommendresult():
cursor = db.cursor()
data = format2(getMaxId())
num = getMaxId()
for i in range(num):
result = recommend(str(i+1), data)
for j in range(len(result)):
value = (i+1,result[j][0])
sql = "INSERT INTO recommendations (user_id, news_id) VALUES(%s,%s)"
cursor.execute(sql, value)
db.commit()
db.close()