一个基于协同过滤算法的简易电影推荐系统

最近增在倒腾电影推荐算法,看了一些文章,照葫芦画瓢的练了一下手。

算法为协同过滤算法,

该算法的好处是:

  1. 能起到意想不到的推荐效果, 经常能推荐出来一些惊喜结果
  2. 进行有效的长尾item
  3. 只依赖用户行为, 不需要对内容进行深入了解, 使用范围广

该算法的坏处是:

  1. 一开始需要大量的<user,item>行为数据, 即需要大量冷启动数据
  2. 很难给出合理的推荐解释

以下代码来自于这篇文章:碟中谍这么火,我用机器学习做个迷你推荐系统电影 

文章作者使用的是从movielen网上获得的数据集!ml-100k.zip (size: 5 MB, checksum)

不过本人在使用的过程中,u.item因为编码的问题有错误,转为UTF-8编码即可。

import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

user_file = 'G:\\DeepLearn\\训练集\\ml-100k\\u.data'
movie_file = 'G:\\DeepLearn\\训练集\\ml-100k\\u.item'

user_df = pd.read_csv(user_file, sep='\t', names=['user_id', 'item_id', 'rating', 'timestamp'])
movie_df = pd.read_csv(movie_file, encoding='utf-8', sep='|', usecols=['movie_id', 'movie_title', 'release_date'],
                       names=['movie_id', 'movie_title', 'release_date', 'video_release_date', 'IMDb URL', 'unknown',
                              'Action', 'Adventure', 'Animation', 'Children', 'Comedy', 'Crime', 'Documentary',
                              'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi',
                              'Thriller', 'War', 'Western'])

n_users = user_df.user_id.unique().shape[0]
n_items = user_df.item_id.unique().shape[0]

data_matrix = np.zeros((n_users, n_items))
for line in user_df.itertuples():
    data_matrix[line[1] - 1, line[2] - 1] = line[3]

print(data_matrix)

item_similarity = cosine_similarity(data_matrix.T, dense_output=True)
print(item_similarity)


def movie_rescsys(keywords, k):
    keywords = keywords.title()
    movie_list = []
    try:
        movieid = list(movie_df[movie_df['movie_title'].str.contains(keywords)].movie_id)[0]
        movie_similarity = item_similarity[movieid - 1]
        movie_similarity_index = np.argsort(-movie_similarity)[:k + 1]

        for i in movie_similarity_index:
            rec_movies = list(movie_df[movie_df.movie_id == (i + 1)].movie_title)
            rec_movies.append(movie_similarity[i])
            rec_movies.append(len(user_df[user_df.item_id == (i + 1)]))
            rec_movies.append(user_df[user_df.item_id == (i + 1)]['rating'].mean())
            movie_list.append(rec_movies)
    except:
        print('提示:找不到该电影!请检查输入!')
    return movie_list


def main():
    name = input('请输入电影名称或者关键词:')
    num = int(input('您希望找到多少部相关电影(请输入整数):'))
    result = movie_rescsys(name, num)
    print(result)
    movie_id = list(movie_df[movie_df['movie_title'] == result[0][0]].movie_id)[0]
    choice = input('是否设置相似度阈值(y/n)')


main()

不得不说,这个算法还是不错的,搜索出来的电影相关度非常好。所以本人有点蠢蠢欲动,想用更大一点的数据集进行训练,看看效果如何。选择了稍微大一点的数据集:ml-latest-small.zip (size: 1 MB)

但是把这个数据集直接带入原来的代码中,是不行的。这个数据集的电影表的序号不是按顺序排列的,虽然只用9742条电影,但是序号居然排到了193609。所以在带入原有代码的时候,运行到这行便会出现越界问题:

for line in user_df.itertuples():
    data_matrix[line[1] - 1, line[2] - 1] = line[3]

本人的解决方法是直接将原有数据集进行改造,将电影表的序号顺序排列,并将打分表的电影序号替换成新序号。

user_file = 'G:\\DeepLearn\\训练集\\ml-latest-small\\ratings.csv'
    movie_file = 'G:\\DeepLearn\\训练集\\ml-latest-small\\movies.csv'

    user_df = pd.read_csv(user_file, sep=',', names=['user_id', 'item_id', 'rating', 'timestamp'])
    movie_df = pd.read_csv(movie_file, encoding='utf-8', sep=',', usecols=['movie_id', 'movie_title', 'Genres'],
                           names=['movie_id', 'movie_title', 'Genres'])

    i = 1
    file_txt = '';
    movie_id_dic = {}
    for line in movie_df.itertuples():
        movie_id_dic[line[1]] = i
        file_txt += '{},{},{}\r\n'.format(i, line[2], line[3])
        # print('{},{},{}\r\n'.format(i, line[2], line[3]))
        # print('{},{},{}'.format(i, line[1], line[2]))
        i += 1

    f = open('G:\\DeepLearn\\训练集\\ml-latest-small\\movies_new.csv', 'w+', encoding='utf-8', newline='')
    f.seek(0)
    f.truncate()  # 清空文件
    f.write(file_txt)
    f.close()

    i = 1
    file_txt = '';
    for line in user_df.itertuples():
        file_txt += '{},{},{},{}\r\n'.format(line[1], movie_id_dic[line[2]], line[3], line[4])
        # print('{},{},{},{}\r\n'.format(line[1], movie_id_dic[line[2]], line[3], line[4]))
        # print('{},{},{}'.format(i, line[1], line[2]))
        i += 1

    f = open('G:\\DeepLearn\\训练集\\ml-latest-small\\ratings_new.csv', 'w+', encoding='utf-8', newline='')
    f.seek(0)
    f.truncate()  # 清空文件
    f.write(file_txt)
    f.close()

    user_file = 'G:\\DeepLearn\\训练集\\ml-latest-small\\ratings_new.csv'
    movie_file = 'G:\\DeepLearn\\训练集\\ml-latest-small\\movies_new.csv'

    user_df = pd.read_csv(user_file, sep=',', names=['user_id', 'item_id', 'rating', 'timestamp'])
    movie_df = pd.read_csv(movie_file, encoding='utf-8', sep=',', usecols=['movie_id', 'movie_title', 'Genres'],
                           names=['movie_id', 'movie_title', 'Genres'])

    n_users = user_df.user_id.unique().shape[0]
    print(n_users)
    # n_items = user_df.item_id.unique().shape[0]
    n_items = len(movie_id_dic)
    print(n_items)

    data_matrix = np.zeros((n_users, n_items))
    for line in user_df.itertuples():
        # print(line)
        data_matrix[line[1] - 1, line[2] - 1] = line[3]

    item_similarity = cosine_similarity(data_matrix.T, dense_output=True)
    print(item_similarity)

这样就可以,其他代码不变,有点简单粗暴。有一点还需要提一下,本人在使用这个新的CVS版的数据集之前,为了省事,把header行去掉了。

以下是效果:

请输入电影名称或者关键词:dead
您希望找到多少部相关电影(请输入整数):10

[
    ['Dracula: Dead and Loving It (1995)', 1.0, 19, 2.4210526315789473], 
    ['Fog', 0.567672, 5, 2.1], ['Basic (2003)', 0.53364, 2, 3.75], 
    ['Wrong Turn (2003)', 0.487194, 2, 3.0], 
    ['Batman Beyond: Return of the Joker (2000)', 0.464686, 3, 3.5],
    ['Batman: Under the Red Hood (2010)', 0.462137, 3, 3.6666666666666665], 
    ['Friday the 13th (2009)', 0.449013, 2, 3.0], 
    ['Whistleblower', 0.448733, 2, 3.25], 
    ['Ready to Rumble (2000)', 0.445439, 6, 2.25],
    ['RocketMan (a.k.a. Rocket Man) (1997)', 0.443472, 7, 2.142857142857143], 
    ['All Dogs Go to Heaven 2 (1996)', 0.441771, 11, 3.1818181818181817]
]

这个系统有一个缺陷,就是在搜索关键词的时候,使用字符串比对,以第一个比对上的电影为蓝本进行推荐。所以,虽然推荐的效果已经算不错,但是在以关键词搜索电影的方面,还需要优化。
 

 

 

 

 

 

 

 

 

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
基于协同过滤算法电影推荐系统项目概述: 1. 项目背景:电影推荐系统是一种基于用户行为数据和电影特征数据构建的推荐系统,其目的是为用户提供个性化的电影推荐。协同过滤算法是一种常用的推荐算法,它通过分析用户之间的行为相似性来预测用户对未看过电影的喜好。基于协同过滤算法电影推荐系统可以提高用户的观影体验和满意度,增强用户体验的粘性和活跃度。 2. 用户需求分析:首先,需要分析用户需求,包括用户的观影习惯、兴趣爱好和口味偏好等。此外,还可以通过调研用户反馈和反馈信息收集,了解用户对现有电影推荐系统的满意度和不足之处,以便针对性地改进和优化系统。 3. 数据收集与处理:电影推荐系统需要收集用户行为数据和电影特征数据。用户行为数据包括用户观看的电影、评分、评论等,电影特征数据包括电影的演员、导演、类型、评分、剧情简介等。在收集数据后,需要对数据进行清洗、处理和转换,以便进行后续的推荐算法分析和应用。 4. 协同过滤算法实现:协同过滤算法是一种基于用户行为相似性和物品属性相似性的推荐算法。它根据用户的历史行为和喜好,预测用户对未看过电影的喜好,为用户提供个性化的电影推荐。具体实现过程中,需要设计合理的协同过滤算法模型,例如基于内存的协同过滤算法和基于物品的协同过滤算法等。同时,需要根据数据特征和用户需求调整算法参数和模型参数,以提高推荐准确度和推荐效果。 5. 评估与优化:在协同过滤算法实现后,需要通过测试和评估来验证推荐系统的效果和性能。可以使用一些常用的评估指标,如准确率、召回率、AUC值等来评估推荐系统的性能。同时,可以通过收集用户反馈和用户行为数据来不断优化和改进系统,提高用户的满意度和忠诚度。 总之,基于协同过滤算法电影推荐系统项目旨在为用户提供个性化的电影推荐服务,提高用户的观影体验和满意度。在项目实施过程中,需要充分考虑用户需求、数据收集与处理、协同过滤算法实现和评估与优化等方面,以实现系统的最佳性能和应用效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值