1.简介

要说当今社会最火的行业,当属互联网行业。互联网行业的营收主要由广告收入和用户付费组成。这两项都离不开推荐系统,广告需要给不同用户推荐感兴趣的内容,实现精准营销,而用户付费如视频网站等则需要推荐用户喜欢的内容,增加客户粘性。

作为大数据的典型应用,今天我们来谈谈推荐系统,首先我们简述一下推荐系统的典型算法,并使用业界闻名的Netflix竞赛数据集来实现算法。

问题定义:给定用户行为矩阵X,X为m*n的矩阵,其中m为用户数,n 为内容数。已知X中的一部分值,如何猜测未知值?

2.常用算法

常用算法主要有以下三种

(1)基于内容的算法

给用户推荐与之前该用户评分高的项目相似的项目

构建项目向量:选择一系列的属性,比如电影可分类为恐怖片、爱情片等,并在这些属性上为项目评分,如恐怖属性5分代表惊悚属性最高,从而得知用户喜欢那种类型的项目

优点:不需考虑其他用户、可以推荐符合用户独特品味的项目、易于解释

缺点:很难找到合适的特征、冷启动问题、只能推荐用户喜欢的项目

(2)协同过滤算法

为新用户做推荐时,找到相似的用户喜欢的内容,称为用户-用户协同过滤

确定新内容推荐给哪些用户时,找到相似的内容喜欢的用户,称为内容-内容协同过滤

相似度度量:

(1)Jaccard similarity: 忽视用户评分,只考虑是否看过

(2)Cosine similarity: 使用cos函数度量两个用户的距离,未评分的项目有误差

(3)Pearson correlation: 去均值后度量cosine距离

优点:无需选择特征

缺点:冷启动问题、用户矩阵是稀疏的、一些小众项目无法被推荐

(3)矩阵分解算法

原始的用户-项目m*k矩阵可以分解为两个新矩阵,维度分别为m*k和n*k,原始的矩阵是个稀疏矩阵,通过原有数据进行学习,使用梯度下降法,最终可求出分解后的矩阵,而原始矩阵中的缺失项可以通过训练出的两个矩阵乘积计算

3.代码实现

数据集采用Netflix推荐竞赛的一个子集,包含10000个用户和10000个电影,具体的文件格式如下

(1) 用户列表 users.txt

文件有 10000 行,每行一个整数,表示用户的 id,文件对应本次 Project 的所有用户。

(2) 训练集 netflix_train.txt

文件包含 689 万条用户打分,每行为一次打分,对应的格式为: 用户 id 电影 id 分数 打分日期 其中用户 id 均出现在 users.txt 中,电影 id 为 1 到 10000 的整数。各项之间用空格分开

(3) 测试集 netflix_test.txt

文件包含约 172 万条用户打分,格式与训练集相同。

3.1 数据预处理

将输入文件整理成维度为用户*电影的矩阵 ,其中 对应用户 对电影 的打分

# 导入包

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

# 导入数据

user = pd.read_csv("users.txt", names = ['userid'])

netflix_train = pd.read_csv("netflix_train.txt", sep = ' ', names = ['user_id', 'film_id', 'rating', 'date'])

netflix_test = pd.read_csv("netflix_test.txt", sep = ' ', names = ['user_id', 'film_id', 'rating', 'date'])

# 给用户从零开始进行编号

user['id'] = range(len(user))

netflix_train = netflix_train.merge(user, left_on='user_id', right_on='userid')

netflix_test = netflix_test.merge(user, left_on='user_id', right_on='userid')

# 通过数据透视函数构建用户*电影矩阵

X_train = netflix_train.pivot(index='id', columns='film_id', values='rating')

X_test = netflix_test.pivot(index='id', columns='film_id', values='rating')

# 测试集缺失部分电影,补齐为10000*10000矩阵

for i in range(1, 10001):

if i not in X_test.columns:

X_test[i] = np.nan

X_test = X_test.sort_index(axis=1)

# 查看输出的用户*电影矩阵

print(X_train.head())

print(X_test.head())

3.2 基于用户-用户协同过滤算法的实现

cosine相似度公式:

评分计算:

注意,此处对于未知值的计算,选择与该用户最相近的k个对此项目已评分的用户进行加权平均

(1)首先用argsort()函数求出与用户i最相似的用户,按照相似度倒序排列成列表indexs

(2)其次按照列表indexs进行遍历,找出看过此电影的相似度排名前三的用户并计算对电影评分的加权平均值作为该用户的评分

考虑到一些局部效应的存在,这里对原始算法进行了一些改进,如下图所示

# Collaborate Filtering

# Compute the overall mean and mean by row and column

mu = np.mean(np.mean(X_train))

bx = np.array(np.mean(X_train, axis=1) - mu)

by = np.array(np.mean(X_train, axis=0) - mu)

# Compute the similarity matrix

X = X_train.sub(bx+mu, axis=0) # Demean

X = X.div(np.sqrt(np.sum(np.square(X), axis=1)), axis=0)

X.fillna(0, inplace=True)

similarity_matrix = np.dot(X, X.T)

# Compute the point matrix using CF

X_train = np.array(X_train.fillna(0))

for i in range(X_train.shape[0]):

indexs = np.argsort(similarity_matrix[i, :])[::-1]

for j in range(X_train.shape[1]):

if X_train[i, j] == 0:

sum = 0

num = 0

simi = 0

k = 0

while num < 3 & k < X_train.shape[1]: # top 3

if X_train[indexs[k], j] > 0:

sum = sum + similarity_matrix[i, indexs[k]] * (X_train[indexs[k], j] - mu - bx[indexs[k]] - by[j])

simi = simi + similarity_matrix[i, indexs[k]]

k = k+1

num = num + 1

else:

k = k+1

if simi != 0:

X_train[i, j] = mu + bx[i] + by[j] + sum/simi

else:

X_train[i, j] = mu + bx[i] + by[j]

else:

continue

# Compute RMSE for the algorithm

RMSE = np.sqrt(np.sum(np.sum(np.square(X_train - X_test)))/netflix_test.shape[0])

print(RMSE)

最终计算得到的RMSE为1.013,基线误差(预测得分全部取3的情况)为

,RMSE降低了28.3%

3.3 基于矩阵分解的算法

矩阵分解:

目标函数:

通过梯度下降算法迭代更新目标函数,获取最优分解矩阵U和V

# Matrix Decomposition

A = X_train > 0

X_train = np.array(X_train.fillna(0))

U = np.random.randn(10000, 100)*0.1

V = np.random.randn(10000, 100)*0.1

alpha = 0.0001

lamda = 1

# Gradient Descent

J = np.zeros((1000))

RMSE = np.zeros((1000))

for i in range(200):

dU = np.dot(np.multiply(A, (np.dot(U, V.T) - X_train)), V) + 2 * lamda * U

dV = np.dot(np.multiply(A, (np.dot(U, V.T) - X_train)), U) + 2 * lamda * V

old_U = U

old_V = V

U = U - alpha/(1+0.1*i) * dU # Learning rate decay

V = V - alpha/(1+0.1*i) * dV

J[i, 0] = 1/2*np.sum(np.sum(np.square(np.multiply(A, (X_train - np.dot(U, V.T)))))) + lamda * np.sum(np.sum(np.square(U)))\

+ lamda * np.sum(np.sum(np.square(V)))

RMSE[i, 0] = np.sqrt(np.sum(np.sum(np.square(np.dot(U, V.T) - X_test)))/netflix_test.shape[0])

print(i)

# Visualization

X = np.dot(U, V.T)

plt.plot(range(1000), RMSE[:, 0])

plt.show()

plt.plot(range(1000), J[:, 0])

plt.show()

print(RMSE[999])

如下图所示为按照上述参数迭代1000次后的结果,随着迭代次数的增多,RMSE显著下降,最后RMSE为1.123,相比于基线误差降低了20.6%

矩阵分解的算法收敛效果与模型中的正则项系数

与矩阵维度k是有关,可以尝试不同的参数组合,通过RMSE与目标函数值来确定最优参数组合,目标函数值随着迭代次数的变化如下图所示,尝试的参数组合分别为

=1, 0.1 以及 矩阵维数k=100, 50, 10 共2*3=6种,每种参数组合迭代200次,迭代结果如下图所示,可以选择收敛最快的参数组合进行训练

4.总结

从上文我们可以看出推荐系统的核心问题是确定用户-内容矩阵(Utility Matrix)

(1)收集已知矩阵信息

通过让用户打分或者收集用户的行为数据

(2)从已知矩阵推测未知矩阵信息

通过基于内容的方法、协同过滤方法或者矩阵分解方法推测未知矩阵信息

(3)评价推测方法

常用的标准是RMSE均方根误差

本文的所有代码以及数据集见下面Github链接,大家可以自行下载取用

python写电影推荐系统_Netflix电影推荐系统Python实现(协同过滤+矩阵分解)相关推荐

  1. Python+Django+Mysql实现在线电影推荐系统 基于用户、项目的协同过滤推荐在线电影系统 代码实现 源代码下载

    Python+Django+Mysql实现在线电影推荐系统(基于用户.项目的协同过滤推荐算法) 一.项目简介 1.开发工具和实现技术 pycharm2020professional版本,python3 ...

  2. 在线电影推荐网 使用Python+Django+Mysql开发技术 在线电影推荐系统 电影网站推荐系统 基于用户、物品的协同过滤推荐算法 个性化推荐算法开发 机器学习、人工智能、大数据分布式开发

    在线电影推荐网 使用Python+Django+Mysql开发技术 在线电影推荐系统 电影网站推荐系统 基于用户.物品的协同过滤推荐算法 个性化推荐算法开发 机器学习.人工智能.大数据分布式开发 Mo ...

  3. mysql项目案例电影_Python+Django+Mysql实现在线电影推荐系统 基于用户、项目的协同过滤推荐在线电影系统 代码实现 源代码下载...

    Python+Django+Mysql实现在线电影推荐系统(基于用户.项目的协同过滤推荐算法) pycharm2020professional版本,python3.8版本,django3.1.1版本, ...

  4. 使用Java语言开发在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户、物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis)开发框架 机器学习、人工智能、大数据开发

    使用Java语言开发在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户.物品的协同过滤推荐算法实现 SSM(Spring+SpringMVC+Mybatis)开发框架 机器学习.人工智能.大数据开发 ...

  5. 使用Java+SSM框架+JSP开发简单在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户、物品的协同过滤推荐算法 大数据 机器学习 SimpleMovieRecommendOnline

    使用Java+SSM框架+JSP开发简单在线电影推荐网 电影推荐系统 豆瓣电影爬虫 基于用户.物品的协同过滤推荐算法 大数据 机器学习 SimpleMovieRecommendOnline 一.项目简 ...

  6. Python语言Flask开发框架实现个性化新闻推荐网 在线新闻推荐系统 基于用户、物品的协同过滤推荐算法开发

    Python语言Flask开发框架实现个性化新闻推荐网 在线新闻推荐系统 基于用户.物品的协同过滤推荐算法开发WebNewsRecSystemPython 一.项目简介 1.开发工具和使用技术 Pyt ...

  7. 如何使用Python+Django+Mysql开发个性化职位推荐系统 招聘网站推荐系统 基于用户、项目的协同过滤推荐算法 基于内容、聚类、关联规则推荐算法WebPositionCFRSPython

    如何使用Python+Django+Mysql开发个性化职位推荐系统 招聘网站推荐系统 基于用户.项目的协同过滤推荐算法 基于内容.聚类.关联规则推荐算法WebPositionCFRSPython 一 ...

  8. 推荐系统入门(二):协同过滤(附代码)

    推荐系统入门(二):协同过滤(附代码) 目录 推荐系统入门(二):协同过滤(附代码) 引言 1. 相似性度量方法 1.1 杰卡德(Jaccard)相似系数 1.2 余弦相似度 1.3 皮尔逊相关系数 ...

  9. 推荐系统笔记:基于SVD的协同过滤

    1 奇异值分解 奇异值分解(SVD)是矩阵分解的一种形式,其中U和V的列被约束为相互正交 相互正交的优点是概念之间可以完全独立,并且可以用散点几何解释它们. 然而,这种分解的语义解释通常比较困难,因为 ...

  10. 吴恩达机器学习(十四)推荐系统(基于梯度下降的协同过滤算法)

    目录 0. 前言 1. 基于内容的推荐算法(Content-based recommendations) 2. 计算电影特征 3. 基于梯度下降的协同过滤算法(Collaborative filter ...

最新文章

  1. python怎么删除特定文件_如何使用python从文件中删除特定行?
  2. Linux C编程--进程介绍6--进程的各种标识
  3. Windos下navcat连接虚拟机中的mysql
  4. 多功能网址导航源码 包含交易系统等多功能
  5. 智能会议系统(16)---LinphoneService
  6. fscapture设置中文_Fscapture是什么软件?有没有功能介绍?
  7. 求二叉树的深度(C++)
  8. vue组件化开发学习笔记-3-组件插槽
  9. Android计算器 (课程设计项目)
  10. Hybrid Astar 算法剖析和实现(一)
  11. 最新金色版萝卜影视源码/原生视频影视系统APP源码
  12. 火狐浏览器配置xpath
  13. 浏览器不能上网,QQ能登录 问题解决方法
  14. 二十四小时不插电生活方案
  15. 高等数学---不定积分的计算---基本积分法
  16. 计算机英文积累(一)
  17. 利用ptython中的tutle画了一个表情包——2020冲冲冲!!
  18. 如何实现调用阿里云三方的api
  19. Java代码清除Word文档的批注和修订 (Aspose.Words) Java老铁们,亲测有效!
  20. 百度地图 - 绘制海量点

热门文章

  1. 短视频网站源码干货分享:如何实现背景音乐和美颜功能
  2. HDU 5468 Puzzled Elena (2015年上海赛区网络赛A题)
  3. 2021金三银四面试季!mysql下载安装教程5.7.27
  4. 还有在用迅雷7的朋友吗?
  5. FileUtils(文件读写操作工具类)
  6. IOS github客户端操作流程 超详细
  7. 《软件体系结构》第三章 软件体系结构风格
  8. 过来康康,一起来学VScode插件
  9. Dalamud:FFXIV插件框架和API-源码
  10. 天天生鲜商品详情页HTML+css