Python实现推荐系统

两种最普遍的推荐系统的类型是基于内容和协同过滤(CF)。协同过滤基于用户对产品的态度产生推荐,基于内容的推荐系统基于物品属性的相似性进行推荐。CF可以分为基于内存的协同过滤和基于模型的协同过滤。

我们将使用MovieLens数据集,它是在实现和测试推荐引擎时所使用的最常见的数据集之一,包含来自943个用户以及精选的1682部电影的评分。数据下载地址

导入numpy和pandas库


import numpy as np

import pandas as pd

读入u.data数据文件


header = ['user_id', 'item_id', 'rating', 'timestamp']

df = pd.read_csv('u.data', sep = '\t', names = header)

查看用户和电影的数量


n_users = df.user_id.unique().shape[0]

n_items = df.item_id.unique().shape[0]

print 'Number of users = ' + str(n_users) + ' | Number of movies = ' + str(n_items)


Number of users = 943 | Number of movies = 1682

使用scikit-learn库将数据集分割成测试集和训练集,调用Cross_validation.train_test_split根据测试样本的比例(test_size)将数据混洗并分割成两个数据集。


from sklearn import cross_validation as cv

train_data,test_data = cv.train_test_split(df, test_size = 0.25)

基于内存的协同过滤

基于内存的协同过滤方法可以分为两个部分:用户-产品协同过滤和产品-产品协同过滤。用户-产品协同过滤将选取一个特定的用户,基于打分的相似性发现类似于该用户的用户,并推荐那些相似用户喜欢的产品。产品-产品协同过滤会选取一个产品,发现喜欢该产品的用户,并找到这些相似用户还喜欢的其它产品。

用户-产品协同过滤:“喜欢这东西的人也喜欢……”

产品-产品协同过滤:“像你一样的人也喜欢……”

在这两种情况下,从整个数据集构建一个用户产品矩阵。

用户产品矩阵的例子:

计算相似性,并创建一个相似性矩阵。

在产品-产品协同过滤中的产品之间的相似性是通过观察所有对两个产品打分的用户来度量的。

在用户-产品协同过滤中的用户之间的相似性是通过观察所有同时被两个用户打分的产品来度量的。

通常用于推荐系统中的距离矩阵是余弦相似性,其中,打分被看成n维空间中的向量,而相似性是基于这些向量之间的角度进行计算的。用户a和m的余弦相似性可以用下面的公式进行计算:

image
image

要计算产品m和b之间的相似性,使用公式:

image
image

创建用户产品矩阵,针对测试数据和训练数据,创建两个矩阵:


train_data_matrix = np.zeros((n_users,n_items))

for line in train_data.itertuples():

train_data_matrix[line[1]-1, line[2]-1] = line[3]

test_data_matrix = np.zeros((n_users, n_items))

for line in test_data.itertuples():

test_data_matrix[line[1]-1, line[2]-1] = line[3]

使用sklearn的pairwise_distances函数来计算余弦相似性。


from sklearn.metrics.pairwise import pairwise_distances

user_similarity = pairwise_distances(train_data_matrix, metric = "cosine")

item_similarity = pairwise_distances(train_data_matrix.T, metric = "cosine")

已经创建了相似性矩阵:user_similarity和item_similarity,因此,可以通过基于用户的CF应用下面的公式做出预测:

可以将用户k和用户a之间的相似性看成权重,乘以相似用户a(校正的平均评分用户)的评分,这里需要规范化该值,使得打分位于1到5之间,最后对尝试预测的用户的平均评分求和。

基于产品的CF应用下面的公司进行预测,此时无需纠正用户的平均打分


def predict(rating, similarity, type = 'user'):

if type == 'user':

mean_user_rating = rating.mean(axis = 1)

rating_diff = (rating - mean_user_rating[:,np.newaxis])

pred = mean_user_rating[:,np.newaxis] + similarity.dot(rating_diff) / np.array([np.abs(similarity).sum(axis=1)]).T

elif type == 'item':

pred = rating.dot(similarity) / np.array([np.abs(similarity).sum(axis=1)])

return pred


item_prediction = predict(train_data_matrix, item_similarity, type = 'item')

user_prediction = predict(train_data_matrix, user_similarity, type = 'user')

评估

这里采用均方根误差(RMSE)来度量预测评分的准确性

可以使用sklearn的mean_square_error(MSE)函数,其中RMSE仅仅是MSE的平方根。


from sklearn.metrics import mean_squared_error

from math import sqrt

def rmse(prediction, ground_truth):

prediction = prediction[ground_truth.nonzero()].flatten()

ground_truth = ground_truth[ground_truth.nonzero()].flatten()

return sqrt(mean_squared_error(prediction, ground_truth))


print 'User based CF RMSE: ' + str(rmse(user_prediction, test_data_matrix))

print 'Item based CF RMSe: ' + str(rmse(item_prediction, test_data_matrix))


User based CF RMSE: 3.12466203536

Item based CF RMSe: 3.45056350625

可以看出,基于内存的算法很容易实现并产生合理的预测质量。

基于模型的协同过滤

基于模型的协同过滤是基于矩阵分解(MF)的,矩阵分解广泛应用于推荐系统中,它比基于内存的CF有更好的扩展性和稀疏性。MF的目标是从已知的评分中学习用户的潜在喜好和产品的潜在属性,随后通过用户和产品的潜在特征的点积来预测未知的评分。

计算MovieLens数据集的稀疏度:


sparsity = round(1.0 - len(df) / float(n_users*n_items),3)

print 'The sparsity level of MovieLen100K is ' + str(sparsity * 100) + '%'


The sparsity level of MovieLen100K is 93.7%

SVD

一般的方程可以表示为:

image
image

给定m * n矩阵X:

U 是一个(m * r)正交矩阵

S 是一个对角线上为非负实数的(r * r)对角矩阵

V^T是一个(r * n)正交矩阵

S的对角线上的元素被称为X的奇异值。

阵X可以被分解成U,S和V。U矩阵表示对应于隐藏特性空间中的用户的特性矩阵,而V矩阵表示对应于隐藏特性空间中的产品的特性矩阵。

现在,可以通过U, S和V^T的点积进行预测了:


import scipy.sparse as sp

from scipy.sparse.linalg import svds

u, s, vt = svds(train_data_matrix, k = 20)

s_diag_matrix = np.diag(s)

x_pred = np.dot(np.dot(u,s_diag_matrix),vt)

print 'User-based CF MSE: ' + str(rmse(x_pred, test_data_matrix))


User-based CF MSE: 2.72035726617

总结:

实现了简单的协同过滤方法,包括基于内存的CF和基于模型的CF

基于内存的模型是基于产品或用户之间的相似性,这里采用余弦相似性。

基于模型的CD是基于矩阵分解,采用SVD来分解矩阵

标准的协同过滤方法在面对冷启动的情况时表现不佳。

参考资料

Implementing your own recommender systems in Python

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 欢迎关注【机器学习之路】公众号 1。http://www.voidcn.com/blog/u013713010/a...
    大海一滴写字的地方阅读 4,657评论 0 16
  • 推荐系统的主要方法 一、基于内容的推荐算法 网络基于内容的推荐系统,也称CB(Content-based Reco...
    Arya鑫阅读 3,519评论 1 6
  • 什么是协同过滤 协同过滤推荐(Collaborative Filtering recommendation)是在信...
    小灰灰besty阅读 34,131评论 7 51
  • 这篇文章的技术难度会低一些,主要是对推荐系统所涉及到的各部分内容进行介绍,以及给出一些推荐系统的常用算法,比起技术...
    我偏笑_NSNirvana阅读 12,058评论 5 89
  • 说起要去我家的事情,我一头乱麻。姑姑说借辆车,我怕好久没碰过车,又不是自己的。想了一圈,表姐不可靠,必然会背后给我...
    伤城满楼阅读 180评论 0 0