在日常的数据挖掘工作中,除了使用Python来处理分类或预测任务外,有时还会涉及到推荐系统相关的任务。推荐系统用于各个领域,常见示例包括视频和音乐服务的播放列表生成器、在线商店的产品推荐器或社交媒体平台的内容推荐器。在这个项目中,我们创建了一个电影推荐器。协同过滤通过收集有关许多用户的偏好或品味的信息来自动预测(过滤)用户的兴趣。迄今为止,推荐系统已经发展了很长时间,其模型基于加权平均、相关性、机器学习、深度学习等各种技术。Movielens20M数据集自此以来拥有超过2000万个电影评级和标记事件1995.在本文中,我们将从movie.csv和rating.csv文件中检索信息。使用Python库:Pandas、Seaborn、Scikit-learn和SciPy,使用k最近邻算法的余弦相似度训练模型。以下是该项目的核心步骤:导入和合并数据集并创建PandasDataFrame添加必要的功能来分析数据使用Seaborn可视化数据并分析数据通过设置阈值过滤无效数据创建按用户和列索引的数据电影数据透视表创建KNN模型并输出与每部电影相似的5个推荐导入数据导入和合并数据集并创建PandasDataFrameMovieLens20M数据集自1995年以来超过2000万部电影评级和标记活动。#usecols可以让你选择你选择的特征,通过dtypemovies_df=pd.read_csv('movies.csv',usecols=['movieId','title'],dtype={'movieId':'int32','title':'str'})movies_df.head()ratings_df=pd.read_csv('ratings.csv',usecols=['userId','movieId','rating','timestamp'],dtype={'userId':'int32','movieId':'int32','rating':'float32'})ratings_df.head()检查两个数据中的任何空值和条目数。#检查缺失值movies_df.isnull().sum()movieId0title0dtype:int64ratings_df.isnull().sum()userId0movieId0rating0timestamp0dtype:int64print("Movies:",movies_df.shape)print("Ratings:",ratings_df.shape)Movies:(9742,2)Ratings:(100836,4)合并列上的DataFrame'movieId'#movies_df.info()#ratings_df.info()movies_merged_df=movies_df.merge(ratings_df,on='movieId')movies_merged_df.head()现在已成功合并导入的数据集。添加派生特征以添加必要的特征来分析数据。通过按电影标题对用户评分进行分组来创建“平均评分”和“评分计数”列。movies_average_rating=movies_merged_df.groupby('title')['rating']\.mean().sort_values(ascending=False)\.reset_index().rename(columns={'rating':'AverageRating'})movies_average_rating。head()movies_rating_count=movies_merged_df.groupby('title')['rating']\.count().sort_values(ascending=True)\.reset_index().rename(columns={'rating':'RatingCount'})#ascending=Falsemovies_rating_count_avg=movies_rating_count.merge(movies_average_rating,on='title')movies_rating_count_avg.head()到目前为止已经创建了2个新的衍生特征。数据可视化使用Seaborn对数据进行可视化:一项分析发现,许多电影在近100,000个用户评分的数据集上拥有完美的5星平均评分。这表示异常值,我们需要通过可视化进一步确认。很多电影的评分都比较单一。建议设置评分阈值以产生有价值的推荐。使用seaborn和matplotlib可视化数据,以便更好地观察和分析。绘制新创建的特征的直方图并查看它们的分布。设置binsize为80,这个值的设置需要具体分析,合理设置。#导入可视化库importseabornassnsimportmatplotlib.pyplotaspltsns.set(font_scale=1)plt.rcParams["axes.grid"]=Falseplt.style.use('dark_background')%matplotlibinline#绘制图形plt.figure(figsize=(12,4))plt.hist(movies_rating_count_avg['RatingCount'],bins=80,color='tab:purple')plt.ylabel('RatingsCount(Scaled)',fontsize=16)plt.savefig('ratingcounthist.jpg')plt.figure(figsize=(12,4))plt.hist(movies_rating_count_avg['平均评分'],bins=80,color='tab:purple')plt.ylabel('AverageRating',fontsize=16)plt.savefig('avgratinghist.jpg')图1平均评分直方图图2评分计数直方图现在创建一个joinplot二维图表以将这两个特征一起可视化。plot=sns.jointplot(x='AverageRating',y='RatingCount',data=movies_rating_count_avg,alpha=0.5,color='tab:pink')plot.savefig('joinplot.jpg')AverageRatingandRatingCount的二维图分析图1证实了大多数电影的收视率都很低。除了设置阈值之外,我们还可以针对此用例使用一些更高的百分比分位数。直方图2显示了“平均评分”的分布函数。数据清洗使用describe()函数获取数据集的描述性统计量,如分位数、标准差等。pd.set_option('display.float_format',lambdax:'%.3f'%x)print(rating_with_RatingCount['RatingCount'].describe())count100836.000mean58.759std61.965min1.00025%13.00050%30.080075%329.000Name:RatingCount,dtype:float64设置阈值,过滤掉高于阈值的数据。popularity_threshold=50popular_movies=rating_with_RatingCount[rating_with_RatingCount['RatingCount']>=popularity_threshold]popular_movies.head()#popular_movies.shape到目前为止,通过过滤掉评论低于阈值的电影来清理数据。创建一个数据透视表创建一个以用户为索引,以电影为列的数据透视表为了稍后将数据加载到模型中,您需要创建一个数据透视表。并将“title”设置为索引,将“userId”设置为列,将“rating”设置为值。接下来会创建importosmovie_features_df=popular_movies.pivot_table(index='title',columns='userId',values='rating').fillna(0)movie_features_df.head()movie_features_df.to_excel('output.xlsx')数据透视表已加载到模型中。BuildakNNmodel构建kNN模型,输出5个类似每部电影的推荐使用scipy.sparse模块中的csr_matrix方法,将pivottable转换为数组矩阵,用于拟合模型。fromscipy.sparseimportcsr_matrixmovie_features_df_matrix=csr_matrix(movie_features_df.values)最后,使用之前生成的矩阵数据从sklearn训练NearestNeighbors算法。并设置参数:metric='cosine',algorithm='brute'fromsklearn.neighborsimportNearestNeighbors'kneighbors'算法需要将数据转换成单行数组,设置n_neighbors的值。query_index=np.random.choice(movie_features_df.shape[0])distances,indices=model_knn.kneighbors(movie_features_df.iloc[query_index,:].values.reshape(1,-1),n_neighbors=6)最后在query_index输出电影推荐。foriinrange(0,len(distances.flatten())):ifi==0:print('Recommendationsfor{0}:\n'.format(movie_features_df.index[query_index]))else:print('{0}:{1},距离为{2}:'.format(i,movie_features_df.index[indices.flatten()[i]],distances.flatten()[i]))哈利波特的推荐和凤凰社(2007):1:哈利波特与混血王子(2009),距离为0.2346513867378235:2:哈利波特与凤凰社(2007),距离为0.3396233320236206:3:哈利·波特与火焰杯(2005),距离为0.4170845150947571:4:哈利·波特与阿兹卡班的囚徒(2004),距离为0.4499547481536865:5:哈利·波特与密室(2002),距离为0.4506162405014038:到目前为止,我们已经成功地构建了一个仅基于用户评分的推荐引擎。总结以下是我们构建电影推荐系统的步骤总结:导入和合并数据集并创建PandasDataFrame创建派生变量以更好地分析数据使用Seaborn可视化数据通过设置阈值清理数据ColumnPivotTable构建一个kNN模型并输出与每部电影最相似的5个推荐写在最后以下是您可以扩展项目的一些方法:这个数据集不是很大,可以包含在项目的包含数据集中其他文件来扩展这个项目的范围.“ratings.csv”中的时间戳可用于分析评分随时间的变化情况,我们可以在解析模型时根据时间戳对评分进行加权。该模型的性能比加权平均或相关模型要好得多,但仍有改进的空间,例如使用高级ML算法甚至DL模型。
