基于用户的协同过滤电影推荐简单实现

本文介绍了如何通过Python编程,利用pandas和Scikit-learn库处理数据集,计算用户间的余弦相似度,然后运用K近邻算法为用户推荐电影。过程包括合并数据、创建用户评分矩阵、计算相似度并应用KNN模型,最终输出个性化推荐列表。
摘要由CSDN通过智能技术生成

1.数据集的准备

movies = pd.read_csv('movies.csv')
ratings = pd.read_csv('ratings.csv')
#合并数据集
df = pd.merge(ratings, movies, on='movieId')
#转为用户评分矩阵
user_movie_ratings = df.pivot_table(index='userId', columns='title', values='rating')
#未评分补充为0
user_movie_ratings = user_movie_ratings.fillna(0)

2.计算用户的相似矩阵(基于用户)
user_similarity = cosine_similarity(user_movie_ratings, user_movie_ratings)
#使用余弦相似度

余弦相似度:余弦相似度是通过计算两个向量之间的夹角的余弦值来度量它们的相似性。

用户评分表的为用户的评分向量,计算结果表示对电影打分的相似程度。

3.使用K 最近邻算法模型计算临近用户
knn = NearestNeighbors(n_neighbors=5, metric='cosine', algorithm='brute')
knn.fit(user_movie_ratings)

·NearestNeighbors 类来自于 scikit-learn 库,它实现了K最近邻算法。在这里,我们创建了一个KNN模型对象 knn。

·n_neighbors=5:这个参数指定了在搜索时要考虑的最近邻居的数量。在这里,我们将考虑每个用户的5个最相似的用户。

·metric='cosine':这个参数指定了用于度量距离的度量方式。在这里,我们使用余弦距离作为度量方式,这与我们之前计算用户相似度时使用的度量方式相一致。

·algorithm='brute':这个参数指定了用于搜索最近邻的算法。在这里,我们使用 'brute' 算法,它会对所有的样本进行暴力搜索来找到最近邻。虽然这种方法可能效率较低,但对于较小的数据集来说是可行的。

得到相似用户 

distances, indices = knn.kneighbors([user_movie_ratings.iloc[user_index]])

#distances:这是一个数组,包含了指定用户与其最近邻用户之间的距离。
#indices:这是一个数组,包含了指定用户的最近邻用户的索引。

4. 推荐逻辑
# 获取与指定用户最相似的用户列表
    similar_users = indices[0]
# 修正相似用户的数量
    num_similar_users = len(similar_users)


    if num_similar_users > 0:

        #这一行代码通过提取目标用户与最相似用户之间的相似度,创建了一个一维数组。
        user_similarity = user_similarity[user_index, similar_users]
        #转为向量,方便计算
        user_similarity = user_similarity.reshape(1, num_similar_users)

        # 获取相似用户的评分信息
        similar_users_ratings = user_movie_ratings.iloc[similar_users]

        print(similar_users_ratings)

        # 处理用户未评分的电影
        unrated_movies = user_movie_ratings.iloc[user_index] [user_movie_ratings.iloc[user_index] == 0].index

        # 初始化一个字典来存储电影的推荐分数
        recommendations = {}

        # 遍历相似用户列表

        for user in range(num_similar_users):

            # 获取相似用户评分过的电影

            similar_rated_movies = similar_users_ratings.columns[similar_users_ratings.iloc[user] != 0]


            # 获取相似用户未评分的电影
            similar_unrated_movies = similar_users_ratings.iloc[user][unrated_movies]

            # 计算推荐分数,只考虑相似用户已经评分和目标用户未评分过的电影
            common_movies = list(set(similar_rated_movies) & set(unrated_movies))


            if len(common_movies) > 0:

#当前相似用户对推荐用户的推荐分数,通过相似度加权得到。
                recommendation_scores = similar_users_ratings.iloc[user][common_movies].values.dot(
                    user_similarity[0, user])


                # 更新推荐分数字典,将每个相似用户的推荐分数相加
                for i, movie in enumerate(common_movies):
                    if movie not in recommendations:
                        recommendations[movie] = 0
                    recommendations[movie] += recommendation_scores[i]


        # 对推荐分数进行排序,得到排名前几的电影
        sorted_recommendations = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)

        # 获取最大和最小的推荐分数
        max_score = max(sorted_recommendations, key=lambda x: x[1])[1]
        min_score = min(sorted_recommendations, key=lambda x: x[1])[1]


        # 归一化推荐分数到0到5之间
        normalized_recommendations = [(movie, (score - min_score) / (max_score - min_score) * 5) for movie, score in
                                      sorted_recommendations]

        # 输出归一化后的推荐列表
        print("归一化后的推荐电影列表:")
        for movie, score in normalized_recommendations[:10]:
            print(f"{movie}: {score}")

线性归一化

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值