用Python构建你自己的推荐系统

用Python构建你自己的推荐系统

  现如今,网站用推荐系统为你提供个性化的体验,告诉你买啥,吃啥甚至你应该和谁交朋友。尽管每个人口味不同,但大体都适用这个套路。人们倾向于喜欢那些与自己喜欢的其他东西相似的东西,也倾向于与自己身边的人有相似的口味。推荐系统就尝试捕捉这一规律来帮助预测你也可能喜欢的其他东西。

  为帮用户高效挑选商品,电子商务、社交媒体、视频和在线新闻平台已积极部署了他们自己的推荐系统,这是一个双赢的策略。

  

  推荐系统两个最普遍的类型是基于内容过滤法和协同过滤法。协同过滤法基于用户对商品的评价信息来产生推荐,是用大众的智慧来推荐内容。相比之下,基于内容推荐系统关注的是商品的属性,基于它们之间的相似度给你推荐。

  大体上,协同过滤(CF)是推荐引擎工作的是主力。这一算法有一个很有趣的特点,它能够自主学习,这意味着它能够开始学习哪些特点能为己所用。协同过滤又可分为基于内存的协同过滤和基于模型的协同过滤。在此教程中,你将实现运用奇异值分解的基于模型协同过滤法和通过计算余弦相似性的基于内存协同过滤法。

  我们将使用MovieLens数据集,这是用来实现和测试推荐引擎最普遍的数据集之一。它包含来自于943个用户的10万个电影评价和1682部电影集合。你最好将这个数据集(MoviesLens-100k)解压到你的notebook目录。

  

  


1

2

import numpy as np

import pandas as pd

 u.data文件中包含了完整数据集。你可以在这里查阅关于这个数据集的简要描述


1

2

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

df = pd.read_csv(‘ml-100k/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 模块根据测试样本的百分比将数据混合并分为两部分,在这里百分比为0.25

from sklearn import cross_validation as cv
train_data, test_data = cv.train_test_split(df, test_size=0.25)

基于内存协同过滤法

  基于内存协同过滤法可以被主要分为两部分:用户-项目过滤(user-item filtering项目-项目过滤( item-item filtering user-item filtering选取一个特定用户,基于评价相似性找到与该用户相似的其他用户,并推荐那些相似用户所喜欢的项目。相比之下, item-item filtering 先选取一个项目,然后找出也喜欢这个项目的其他用户,并找出这些用户或相似用户也喜欢的其他项目,推荐过程需要项目并输出其他项目。

  • Item-Item Collaborative Filtering: “Users who liked this item also liked …”
  • User-Item Collaborative Filtering: “Users who are similar to you also liked …”

在这两种情况中,你根据整个数据集创建了一个用户-项目的矩阵。因为已经把数据分成了测试和训练两部分所以你需要创建两个[943 x 1682]矩阵。训练矩阵包含75%的评价,测试矩阵包含25%的矩阵。

用户-项目矩阵例子:

创建了用户-项目矩阵之后,计算相似性并创建一个相似度矩阵。

Item-Item Collaborative Filtering算法中项目之间的相似度依靠观测所有的已对相同项目评价的用户来测算。

对于User-Item Collaborative Filtering算法,用户之间的相似性依靠观测相同用户已评价的所有项目。

  推荐系统中通常使用余弦相似性作为距离度量,在n维孔空间中评价被视为向量,基于这些向量之间的夹角来计算相似性。

  用户am可以用下面的公式计算余弦相似性,其中你可以使用用户向量ukua之间的点积然后除以这两个向量欧式长度之乘。

  而计算项目m和b之间的相似度可以用下面的公式:

首先创建user-item矩阵,因此你需要创建两个矩阵为测试和训练数据集。


1

2

3

4

5

6

7

8

#Create two user-item matrices, one for training and another for testing

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]

  你可以使用 pairwise_distances函数来计算余弦相似性。注意,因为评价都为正值输出取值应为0到1.


1

2

3

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_similarityitem_similarity,因此你可以运用下面的公式为user-based CF做一个预测:

  用户k和用户a之间的相似度根据一个相似用户a的一系列评价的乘积(修正为该用户的平均评价)的权重。你将需要标准化相似度这样可以使评价维持在1到5之间,最后一步,统计你想预测用户平均评价的总和。

  这里考虑到的问题是一些用户评价所有电影时可能要么给最高分,要么给最低分。这些用户给出评价的相对不同比绝对值更重要。例如:设想,用户k对他最喜欢的电影评价4颗星,其他的好电影则评价3颗星。假设现在另一个用户t对他/她喜欢的一部电影评价为5颗星,看了想睡觉的一部电影评价为3颗星。这两位用户电影口味可能很相似但使用评价体系的方法不同。

  当为item-based CF做一个推荐时候,你不要纠正用户的平均评价,因为用户本身用查询来做预测。


1

2

3

4

5

6

7

8

9

def predict(ratings, similarity, type=‘user‘):

    if type == ‘user‘:

        mean_user_rating = ratings.mean(axis=1)

        #You use np.newaxis so that mean_user_rating has same format as ratings

        ratings_diff = (ratings - mean_user_rating[:, np.newaxis])

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

    elif type == ‘item‘:

        pred = ratings.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‘)

评估  

有许多的评价指标,但是用于评估预测精度最流行的指标之一是Root Mean Squared Error (RMSE)。

你可以用sklearn中的 mean_square_error (MSE)函数,RMSE只是MSE其中的一个平方根。想阅读更多关于不同评估指标你可以 查看这篇文章

因为你仅仅想考虑在这个测试数据集中的预测评价,你可以用prediction[ground_truth.nonzero()]过滤测试矩阵中所有其他的元素。


1

2

3

4

5

6

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))

  


1

2

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

print ‘Item-based CF RMSE: ‘ + str(rmse(item_prediction, test_data_matrix))

  


1

2

User-based CF RMSE: 3.1236202241

Item-based CF RMSE: 3.44983070639

  

Memory-based算法容易实施并产生合理的预测质量。memory-based CF的缺点是它不能扩展到现实世界的场景和没有处理众所周知的冷启动问题(面对新用户或者新项目进去系统时)。Model-based CF方法可伸缩并且能处理 比memory-based方法更高等级的稀疏度,面对新用户或者没有任何评价的新项目进入系统时也会变差。我想感谢Ethan Rosenthal关于Memory-Based Collaborative Filtering的博客

Model-based Collaborative Filtering

基于模型的协同过滤是基于已收到更大的曝光,主要是作为潜变量分解和降维无监督的学习方法矩阵分解(MF)

Model-based Collaborative Filtering基于已收到很多曝光的矩阵因式分解 (MF),主要是作为潜在变量分解和降维无监督学习方法。矩阵因式分解因其能比Memory-based CF更好解决可扩展性和稀疏问题而被广泛用于推荐系统。MF的目标是学习用户潜在的喜好和从已知评分的项目的潜在属性(学习描述评分特征的特点),以随后通过用户和项目的潜在特征点积预测未知的评分。

当你有一个多维度稀疏矩阵,通过矩阵因式分解你能够将用户-项目矩阵(user-item matrix)重构成低评分结构(low-rank structure),并且你能够通过两个低评分( low-rank)矩阵相乘得出这个矩阵,其中矩阵的行包含潜在向量。

通过低评价矩阵乘积尽可能调整这个矩阵近似原始矩阵,以填充原始矩阵中缺失的项。

现在开始计算MovieLens 数据集的稀疏等级:


1

2

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

print ‘The sparsity level of MovieLens100K is ‘ +  str(sparsity*100) + ‘%‘

  


1

The sparsity level of MovieLens100K is 93.7%

  举个例子说明学习用户和项目的潜在喜好:就拿MovieLens数据集来说你有一下信息:(用户ID,年龄,地理位置,性别,电影ID,导演,演员,语言,年份,评分)。通过运用矩阵因式分解这个模型学习到重要的用户特征是年龄段(10岁以下、10-18岁、18-30岁、30-90岁)、地理位置和 性别,对电影特征它学习到最重要的是年代、导演和演员。现在如果你回过头来看你已经存储的信息,没有诸如年代等的特征,但是这个模型可以自己学习到。重要的方面是CF模型仅需使用数据(用户ID,电影ID,评分)来学习这些潜在的特征。如果没有数据可用CF模型性能将会很差,因为这样它更困难学习这些潜在的特征。

评分和特征都要使用的模型称为混合推荐系统(Hybrid Recommender Systems),它是Collaborative Filtering 和Content-based 模型两者的结合。混合推荐系统通常比Collaborative Filtering 或者Content-based模型独立地表现出更高的精度:它们能够更好地处理冷启动问题(因为如果你没有可用于数据集的对于用户或项目的任何评价你就很难做出预测)。混合推荐系统将在下一篇介绍中介绍。

SVD

一个知名的矩阵因式分解方法是Singular value decomposition (SVD)。Collaborative Filtering
协同过滤可以通过使用奇异值分解近似矩阵X被配制

本文翻译自:http://online.cambridgecoding.com/notebooks/eWReNYcAfB/implementing-your-own-recommender-systems-in-python-2

原作者:Agnes Jóhannsdóttir

原文地址:https://www.cnblogs.com/fengff/p/9556649.html

时间: 2024-10-31 19:07:29

用Python构建你自己的推荐系统的相关文章

实战:基于Python构建运维自动化平台

导语: 今天与大家一起探讨如何基于Python构建一个可扩展的运维自动化平台,也希望能与大家一起交流,共同成长. 此次分享将通过介绍OMServer.OManager具备的功能.架构设计.模块定制.安全审计.C/S结构的实现等几个方面的内容来展开. 为什么选择Python? 默认安装且跨平台 可读性好且开发效率高 丰富的第三方库(开发框架.各类API.科学计算.GUI等) 社区活跃&众多开发者. Python在腾讯的现状,根据去年内部提交组件语言统计,除去2.3.4前端技术,Python在高级编

如何基于Python构建一个可扩展的运维自动化平台

嘉宾简介 刘天斯 从事互联网运维工作已13年,目前就职于腾讯-互动娱乐部,负责游戏大数据的运营,曾就职于天涯社区,担任首席架构师/系统管理员. 热衷开源技术的研究,包括系统架构.运维开发.负载均衡.缓存技术.数据库.NOSQL.分布式存储.消息中间件.大数据及云计算.Mesos.Docker.DevOps等领域.擅长大规模集群的运维工作,尤其在自动化运维方面有着非常丰富的经验.同时热衷于互联网前沿技术的研究,活跃在国内社区.业界技术大会,充当一名开源技术的传播与分享者. 导言 受 Reboot

Python 构建方便的函数调用

CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-7-14 @author: guaguastd @name: convenient_function_call.py ''' if __name__ == '__main__': # import json import json # import search from search import twitter_search # import twitter

使用Boost.Python构建混合系统(译)

目录 Building Hybrid Systems with Boost.Python 摘要(Abstract) 介绍(Introduction) 设计目标 (Boost.Python Design Goals) Hello Boost.Python World 库概述 (Library Overview) 类公开 (Exposing Classes) 序列化 Serialization 对象接口 Object interface 考虑混合编程 Thinking hybrid 开发历史 Dev

spark机器学习系列:(三)用Spark Python构建推荐系统

上一篇博文详细介绍了如何使用Spark Python进行数据处理和特征提取,本系列从本文开始,将陆续介绍用Spark Python对机器学习模型进行详细的探讨. 推荐引擎或许是最为大众所知的一种机器学习模型.人们或许并不知道它确切是什么,但在使用Amazon.Netflix.YouTube.Twitter.LinkedIn和Facebook这些流行站点的时候,可能已经接触过了.推荐是这些网站背后的核心组件之一,有时还是一个重要的收入来源. 推荐引擎背后的想法是预测人们可能喜好的物品并通过探寻物品

如何用Python搭建一个简单的推荐系统?

推荐系统的相关知识我们已在前文中提到,在这篇文章中,我们会介绍如何用Python来搭建一个简单的推荐系统. 本文使用的数据集是MovieLens数据集,该数据集由明尼苏达大学的Grouplens研究小组整理.它包含1,10和2亿个评级. Movielens还有一个网站,我们可以注册,撰写评论并获得电影推荐.接下来我们就开始实战演练. 在这篇文章中,我们会使用Movielens构建一个基于item的简易的推荐系统.在开始前,第一件事就是导入pandas和numPy. import pandas a

通过python 构建一个简单的聊天服务器

构建一个 Python 聊天服务器 一个简单的聊天服务器 现在您已经了解了 Python 中基本的网络 API:接下来可以在一个简单的应用程序中应用这些知识了.在本节中,将构建一个简单的聊天服务器.使用 Telnet,客户机可以连接到 Python 聊天服务器上,并在全球范围内相互进行通信.提交到聊天服务器的消息可以由其他人进行查看(以及一些管理信息,例如客户机加入或离开聊天服务器).这个模型如图 1 所示. 图 1. 聊天服务器使用 select 方法来支持任意多个客户机 聊天服务器的一个重要

spark机器学习笔记:(五)用Spark Python构建分类模型(下)

声明:版权所有,转载请联系作者并注明出处  http://blog.csdn.net/u013719780?viewmode=contents 博主简介:风雪夜归子(英文名:Allen),机器学习算法攻城狮,喜爱钻研Meachine Learning的黑科技,对Deep Learning和Artificial Intelligence充满兴趣,经常关注Kaggle数据挖掘竞赛平台,对数据.Machine Learning和Artificial Intelligence有兴趣的童鞋可以一起探讨哦,

Python 构建工具 buildout 的介绍与使用

来到了新公司上班,首先就是得把自己的环境给搭起来.知乎使用了buildout作为python项目的构建工具. 那么什么是 buildout ? buildout的是一款自动化构建工具.由Zope团队开发维护.包名为zc.buildout. buildout可以为应用构建独立的依赖环境.类似于virtualenv,但二者还有不同.粗略地讲,buildout支持的功能更多更便于自动化而且具体定位有所不同. 首先我们建立一个 python 独立环境的沙盒,不管是 virtualenv 还是 minic