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协同过滤电影推荐的论文_协同过滤?教你用Python实现协同过滤

    提到ALS相信大家应该都不会觉得陌生,它是协同过滤的一种,并被集成到Spark的Mllib库中.本文就ALS的基本原理进行讲解,并手把手.肩并肩地带您实现这一算法. 协同过滤?教你用Python实现协 ...

  2. python中小学生编程学习-推荐几个适合小白学习Python的免费网站

    9gd少儿编程网-Scratch_Python_教程_免费儿童编程学习平台 想要学好python,只靠看Python相关的书籍是远远不够的!互联网时代,我们还要充分利用网络上的免费资源,不然怎样成为一 ...

  3. 电影点评系统论文java_java电影在线定制影评管理系统

    文章来源:淘论文网   发布者:毕业设计 浏览量: 影评网系统模块主要包括网站前台管理和管理员后台管理两部分. 网站前台管理包括注册管理.公告查看.投票管理.网站简介,注册管理包括注册会员及信息的管理 ...

  4. python自学网站免费-推荐几个适合小白学习Python的免费网站

    9gd少儿编程网-Scratch_Python_教程_免费儿童编程学习平台 想要学好python,只靠看Python相关的书籍是远远不够的!互联网时代,我们还要充分利用网络上的免费资源,不然怎样成为一 ...

  5. 矩阵分解java_推荐系统基础:使用PyTorch进行矩阵分解进行动漫的推荐

    我们一天会遇到很多次推荐--当我们决定在Netflix/Youtube上看什么,购物网站上的商品推荐,Spotify上的歌曲推荐,Instagram上的朋友推荐,LinkedIn上的工作推荐--列表还 ...

  6. python实现lfm_推荐系统召回算法之——LFM(矩阵分解)

    目录 1.LFM算法原理 2.LFM数学原理 3.应用场景 4.python实现 5.总结 算法原理:LFM(later factor model)是一种基于矩阵分解的召回算法,输入UI点展矩阵,输出 ...

  7. 电影点评系统论文java_电影评论网站系统毕业设计(论文)论文参考.doc

    电影评论网站系统毕业设计(论文)论文参考 摘 要 在已跨入21世纪的今天,人类使用和学习信息的方式以及信息的包装方式正在进行着不可阻挡的革命.目前,我国上网的人口已经过亿,是世界上网民最多的国家,许多 ...

  8. python编程工具jurtbook_推荐7款好用的Python工具!

    Python数据分析好用的工具有哪些?今天小编为大家推荐七个数据分析师必备的Python工具. Pandas:是一个开源的,BSD许可的库,为Python编程语言提供高性能,易于使用的数据结构和数据分 ...

  9. python爬虫案例_推荐上百个github上Python爬虫案例

    现在学生都对爬虫感兴趣,这里发现一些好的github开源的代码,分享给各位 1.awesome-spider 该网站提供了近上百个爬虫案例代码,这是ID为facert的一个知乎工程师开源的,star6 ...

  10. python实现 基于邻域的算法之协同过滤(电影推荐实战)

    1 介绍 1.1 用户行为数据 用户行为数据通常把包括:网页浏览.购买点击.评分和评论等. 用户行为在个性化推荐系统中一般分为两种: 显性反馈行为(explicit feedback) 包括:用户明确 ...

最新文章

  1. 多路IO复用模型 select epoll 等
  2. php类方法语法错误捕获,php语法错误捕获
  3. [CodeForces1070C]Cloud Computing(2018-2019 ICPC, NEERC, Southern Subregional Contest )
  4. Zabbix小版本升级
  5. echarts做企业关系图谱_echarts 关系图
  6. Just do it
  7. Python Gevent – 高性能的 Python 并发框架
  8. 蓝色大巴汽车网站404页面源码
  9. arduino esp8266_Arduino-httpupdate-OTA-esp8266升级探险记
  10. 关于Shiro的标签应用
  11. PHP正则怎样词语过滤,如何用正则替换敏感词?敏感词过滤? - SegmentFault
  12. conan入门(六):conanfile.txt conanfile.py的区别
  13. 【无头浏览器】谷歌无头浏览器的几行代码简单设置?
  14. 主题:免费的论文查重网站 正文:给大家推荐一个免费的论文查重网站PaperPP:http://www.paperpp.com
  15. 嵌入式 Linux 入门 环境篇(一、开发板初体验)
  16. (七)数字后端之形式验证
  17. java中特殊字符的输出方式_java 特殊符号输出绝对基础?
  18. if [ $# -ne 1 ];then 是什么意思?
  19. 【如何解决 Web 越来越繁杂的问题】笔记
  20. linux内核mproject函数,把linux驱动独立于内核外编译--示例

热门文章

  1. 使用ELK在DC / OS中进行日志管理
  2. ZZULIoj 1913: 小火山的计算能力
  3. 谈论高并发(三)锁的一些基本概念
  4. POJ_1753解答过程的理解
  5. C++--第13课 - 操作符重载 - 下
  6. 数据-第13课-链表回顾
  7. C#的GC机制(来自网摘复制,未整理)
  8. Spring Cloud消息驱动整合
  9. ARM——操作系统—最小操作系统-开发板测试
  10. k邻近算法应用实例(一) 改进约会网站的配对效果