如何用Python构建机器学习推荐系统?网易云、爱奇艺也用这种方法

本文将教大家用Python中基于模型的协同过滤构建推荐系统,这种推荐系统经常被用于音乐、视频网站等 。
推荐系统广泛应用于音乐、电影、书籍、新闻、研究文章、餐馆等产品的推荐 。
如何用Python构建机器学习推荐系统?网易云、爱奇艺也用这种方法

文章插图
 
构建推荐系统有两种常用方法:
  • 协同过滤:https://en.wikipedia.org/wiki/Collaborative_filtering
  • 基于内容的筛选:https://developers.google.com/machine-learning/recommendation/content-based/basics
协同过滤方法通过从许多其他用户(协作)收集偏好信息来预测(过滤)用户对产品的兴趣 。协同过滤方法背后的假设是,如果一个人 P1 和另一个人 P2 对某个问题有相同的意见,P1比随机选择的人更有可能分享P2对不同问题的意见 。
基于内容的过滤方法利用产品特性/属性,根据其他用户之前的行为或对产品的评价等明确反馈,推荐与用户喜欢的产品相似的其他产品 。
推荐系统可以使用这两种方法中的一种或两种 。
在本文中,将使用 Kaggle Netflix prize 数据集来演示如何使用基于模型的协同过滤方法在 Python 中构建推荐系统 。
【如何用Python构建机器学习推荐系统?网易云、爱奇艺也用这种方法】本文其余部分安排如下:
  • 协同过滤概述
  • 用 Python 构建推荐系统
  • 总结
1、协同过滤概述协同过滤背后的主要思想是,一个人经常从另一个兴趣相似的人那里得到最佳推荐 。协同过滤使用各种技术来匹配兴趣相似的人,并基于共同的兴趣给出推荐 。
协同过滤系统的高级工作流程如下:
  • 用户对项目(如电影、书籍)进行评分,以表达他或她对项目的偏好;
  • 系统将评分视为用户对项目兴趣的程度;
  • 系统会将此用户的评分与其他用户的评分进行匹配,并找到具有最相似评分的人;
  • 系统推荐相似用户评分较高但尚未被该用户评分的项目 。
通常,协同过滤系统通过两个步骤向给定用户推荐产品:
  • 第1步:寻找与给定用户共享相同评级模式的人;
  • 第2步:使用步骤1中找到的用户的评分来计算给定用户对产品的评分预测 。
这称为基于用户的协作过滤 。这种方法的一个具体实现是基于用户的最近邻算法 。
另一种选择是,基于项目的协同过滤(例如,对x感兴趣的用户也对y感兴趣)以项目为中心的方式工作:
  • 第1步:建立一个项目--项目矩阵的评分关系对项目;
  • 第2步:通过检查矩阵并匹配用户的评分数据,预测当前用户对产品的评分 。
有两种类型的协同过滤系统:
  • 基于模型
  • 基于内存
在一个基于模型的系统中,我们使用不同的机器学习算法开发模型来预测用户对未评分项目的评分 。基于模型的协同过滤算法有很多,如奇异值分解(SVD)、贝叶斯网络、聚类模型等 。
基于内存的系统使用用户的评分数据来计算用户或项目之间的相似度 。这类系统的典型例子是基于邻域的方法和基于项/基于用户的 top-N 建议 。
本文介绍了如何利用 SVD 模型构建一个基于模型的协同过滤系统 。
2、用Python构建推荐系统下面,将给大家详细介绍用 Python 构建推荐系统的流程 。
2.1 安装库
有多个Python库可用于构建推荐系统(例如 Python scikit Surprise、基于Spark RDD的协同过滤API) 。我在本文中使用 Python scikit Surprise 库进行演示 。
可以按如下方式安装库:
pip install scikit-surprise2.2 加载数据
如前所述,我在本文中使用Kaggle Netflix prize数据集 。有可用于不同目的的多个数据文件 。本文中使用了以下数据文件:
训练数据:
  • Combined_data_1.txt
  • Combined_data_2.txt
  • Combined_data_3.txt
  • Combined_data_4.txt
电影标题数据文件:
  • movie_titles.csv
由于训练数据集太大,无法在笔记本电脑上处理 。因此,为了方便演示,我仅从每个训练数据文件中加载前 100,000 条记录 。
将训练数据文件下载到本地计算机上之后,可以将每个训练数据文件中的前 100,000 条记录作为Pandas 数据帧加载到内存中,如下所示:
def readFile(file_path, rows=100000):data_dict = {'Cust_Id' : [], 'Movie_Id' : [], 'Rating' : [], 'Date' : []}f = open(file_path, "r")count = 0for line in f:count += 1if count > rows:breakif ':' in line:movidId = line[:-2] # remove the last character ':'movieId = int(movidId)else:customerID, rating, date = line.split(',')data_dict['Cust_Id'].Append(customerID)data_dict['Movie_Id'].append(movieId)data_dict['Rating'].append(rating)data_dict['Date'].append(date.rstrip("n"))f.close()return pd.DataFrame(data_dict)df1 = readFile('./data/netflix/combined_data_1.txt', rows=100000)df2 = readFile('./data/netflix/combined_data_2.txt', rows=100000)df3 = readFile('./data/netflix/combined_data_3.txt', rows=100000)df4 = readFile('./data/netflix/combined_data_4.txt', rows=100000)df1['Rating'] = df1['Rating'].astype(float)df2['Rating'] = df2['Rating'].astype(float)df3['Rating'] = df3['Rating'].astype(float)df4['Rating'] = df4['Rating'].astype(float)


推荐阅读