import pandas as pd
import numpy as np
DATA_PATH = "ratings.csv"
def load_data(data_path):
'''
加载数据
return:用户-物品评分矩阵
'''
# 设置要加载的数据字段类型
dtype = {"userId": np.int32, "movieId": np.int32, "rating": np.float32}
# 加载数据(前三列),用户Id,电影Id,以及用户对电影的对应评分
ratings = pd.read_csv(data_path, dtype=dtype, usecols=range(3))
# 透视表(User-Movie的评分矩阵)
ratings_matrix = ratings.pivot_table(index=["userId"], columns=["movieId"], values="rating")
print("数据集加载完毕")
return ratings_matrix
if __name__ == '__main__':
ratings_matrix = load_data(DATA_PATH)
print("ratings_matrix:\n", ratings_matrix)
def compute_pearson_similarity(ratings_matrix, based="user"):
'''
计算皮尔逊相关系数
ratings_matrix:用户-物品评分矩阵
based:user、item
return:相似度矩阵
'''
# 基于皮尔逊相关系数计算相似度
# 用户相似度
if based == "user":
print("开始计算用户相似度矩阵")
similarity = ratings_matrix.T.corr()
else:
print("开始计算物品相似度矩阵")
similarity = ratings_matrix.corr()
print("相似度矩阵计算/加载完毕")
return similarity
if __name__ == '__main__':
ratings_matrix = load_data(DATA_PATH)
user_similar = compute_pearson_similarity(ratings_matrix, based="user")
print("user_similar:\n", user_similar)
item_similar = compute_pearson_similarity(ratings_matrix, based="item")
print("item_similar:\n", item_similar)
# 封装函数:User-Based预测给定用户对给定物品的评分值
# 方法说明:利用原始评分矩阵以及物品间两两相似度,预测指定用户对指定物品的评分。
# 如果无法预测,则抛出异常
def predict(uid, iid, ratings_matrix, user_similar):
print("开始预测用户<%d>对物品<%d>的评分..." % (uid, iid))
# 1.找出uid用户的相似用户
similar_users = user_similar[uid].drop([uid]).dropna()
# 筛选正相关用户
similar_users = similar_users.where(similar_users > 0).dropna()
if similar_users.empty is True:
raise Exception("用户<%d>没有相似用户" % uid)
# 2.从uid用户的近邻相似用户中筛选出对iid物品有评分记录的近邻用户
ids = set(ratings_matrix[iid].dropna().index) & set(similar_users.index)
finally_similar_users = similar_users.loc[list(ids)]
# 3.结合uid用户与其近邻用户的相似度预测uid用户对iid物品的评价
sum_up = 0 # 评分预测公式分子值
sum_down = 0 # 评分预测公式分母值
for sim_uid, similarity in finally_similar_users.iteritems():
# 近邻用户的评分数据
sim_user_rated_movies = ratings_matrix.loc[sim_uid].dropna()
# 近邻用户对iid物品的评分
sim_user_rating_for_item = sim_user_rated_movies[iid]
# 计算分子的值
sum_up += similarity * sim_user_rating_for_item
# 计算分母的值
sum_down += similarity
# 计算预测的评分值并返回
predict_rating = sum_up / sum_down
print("预测用户<%d>对电影<%d>的评分为:%0.2f" % (uid, iid, predict_rating))
return round(predict_rating, 2)
# Item-Based 预测给定用户对给定物品的评分值
def predict(uid, iid, ratings_matrix, user_similar):
print("开始预测用户<%d>对物品<%d>的评分..." % (uid, iid))
# 1.找出id物品的相似物品
similar_items = item_similar[iid].drop([iid]).dropna()
# 筛选正相关物品
similar_items = similar_items.where(similar_items > 0).dropna()
if similar_items.empty is True:
raise Exception("物品<%d>没有相似物品" % iid)
# 2.从iid物品的近邻相似物品中筛选uid用户评分过的物品
ids = set(ratings_matrix[uid].dropna().index) & set(similar_items.index)
finally_similar_items = similar_items.loc[list(ids)]
# 3.结合iid物品与其相似物品的相似度和uid用户对其相似物品的评分,预测uid对iid的评分
sum_up = 0 # 评分预测公式分子值
sum_down = 0 # 评分预测公式分母值
for sim_iid, similarity in finally_similar_items.iteritems():
# 近邻物品的评分数据
sim_item_rated_movies = ratings_matrix.loc[sim_iid].dropna()
# uid用户对相似物品的评分
sim_item_rating_for_user = sim_item_rated_movies[uid]
# 计算分子的值
sum_up += similarity * sim_item_rating_for_user
# 计算分母的值
sum_down += similarity
# 计算预测的评分值并返回
predict_rating = sum_up / sum_down
print("预测用户<%d>对电影<%d>的评分为:%0.2f" % (uid, iid, predict_rating))
return round(predict_rating, 2)
if __name__ == '__main__':
# ratings_matrix = load_data(DATA_PATH)
user_similar = compute_pearson_similarity(ratings_matrix, based="user")
# 预测用户1对物品1的评分
predict(1, 1, ratings_matrix, item_similar)
# 预测用户1对物品2的评分
predict(1, 2, ratings_matrix, item_similar)
def predict_all(uid, ratings_matrix, user_similar):
'''
预测全部评分
uid:用户id
ratings_matrix:用户-物品打分矩阵
user_similar:用户两两间相似度
return:逐个返回预测评分
'''
# 准备要预测的物品的id列表
item_ids = ratings_matrix.columns
# 逐个预测
for iid in item_ids:
try:
rating = predict(uid, iid, ratings_matrix, user_similar)
except Exception as e:
print(e)
else:
yield uid, iid, rating
if __name__ == '__main__':
ratings_matrix = load_data(DATA_PATH)
user_similar = compute_pearson_similarity(ratings_matrix, based="user")
for i in predict_all(1, ratings_matrix, user_similar):
pass
'''
添加过滤规则
'''
def _predict_all(uid, item_ids, ratings_matrix, user_similar):
'''
预测全部评分
:param uid: 用户id
:param item_ids: 要预测的物品id列表
:param ratings_matrix: 用户-物品评分矩阵
:param user_similar: 用户两两间相似度
:return: 逐个返回预测评分
'''
# 逐个预测
for iid in item_ids:
try:
rating = predict(uid, iid, ratings_matrix, user_similar)
except Exception as e:
print(e)
else:
yield uid, iid, rating
def predict_all(uid, ratings_matrix, user_similar, filter_rule=None):
'''
预测全部评分,根据条件进行前置过滤
uid:用户id
ratings_matrix:用户-物品评分矩阵
user_similar:用户间两两相似度
filter_rule:过滤规则(只能四选一,否则抛出异常:“unhot”,“rated",[”unhot“,”rated“],None
return:逐个返回预测评分
'''
if not filter_rule:
item_ids = ratings_matrix.columns
elif isinstance(filter_rule, str) and filter_rule == "unhot":
# 过滤非热门电影
# 统计每部电影的评分数
count = ratings_matrix.count()
# 过滤出评分数高于10的电影,作为热门电影
item_ids = count.where(count > 10).dropna().index
elif isinstance(filter_rule, str) and filter_rule == "rated":
# 过滤用户评分过的电影
# 获取用户对所有电影的评分记录
user_ratings = ratings_matrix.loc[uid]
# 评分范围是1-5,小于6都是评分过的,除此以外是没评分过的
_ = user_ratings < 6
item_ids = _.where(_ == False).dropna().index
elif isinstance(filter_rule, list) and filter_rule == ["unhot", "rated"]:
# 过滤非热门和用户已经评分过的电影
count = ratings_matrix.count()
ids1 = count.where(count > 10).dropna().index
user_ratings = ratings_matrix.loc[uid]
猰貐的新时代
- 粉丝: 1w+
- 资源: 2886
最新资源
- 跨平台编程教育:少儿编程在线培训系统开发
- 知攻善防-应急响应靶机-web2.z25
- 知攻善防-应急响应靶机-web2.z23
- 知攻善防-应急响应靶机-web2.z24
- 数据库管理 Navicat Premium for Mac v17.1.8
- 信息融合项目matlab仿真代码及说明 针对杂波环境多目标跟踪问题,设计目标稀疏的目标运动场景,分别采用PDA和JPDA方法,对目标的状态进行有效估计和实时跟踪 以航迹丢失百分率,位置状态估计精度
- 知攻善防-应急响应靶机-web2.z26
- 知攻善防-应急响应靶机-web2.z27
- 知攻善防-应急响应靶机-web2.z28
- python上课PPT 算法2-列表查找.pptx
- 基于simulink的12 8开关磁阻电机电流斩波、角度位置调速控制、模型预测电流、转矩控制仿真程序
- 知攻善防-应急响应靶机-web2.z29
- 知攻善防-应急响应靶机-web2.z30
- 知攻善防-应急响应靶机-web2.z31
- 知攻善防-应急响应靶机-web2.z33
- 知攻善防-应急响应靶机-web2.z34
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈