python实现基于⽤户的的协同过滤算法
本周学习内容汇报:
学习协同过滤,逻辑回归,因⼦分解机等传统推荐模型,熟悉了每种模型的思想以及它们的优缺点。使⽤MovieLens数据集⽤Python实现基于⽤户的协同过滤算法和基于物品的协同过滤算法和使⽤pytorch复现FM。
1. python实现基于⽤户的的协同过滤算法
算法流程:
1.
1. 数据集处理
使⽤MovieLens数据集 数据集中每个变量代表的意思
userId : ⽤户 ID
movieId : ⽤户看过的电影 ID
rating : ⽤户对所看电影的评分
timestap : ⽤户看电影的时间戳
1.
1. 定义变量
N : 记录⽤户看过的电影数量,如: N[“1”] = 10 表⽰⽤户 ID 为 “1” 的⽤户看过 10 部电影;
python新手代码useridW : 相似矩阵,存储两个⽤户的相似度,如:W[“1”][“2”] = 0.66 表⽰⽤户 ID 为 “1” 的⽤户和⽤户 ID 为 “2” 的⽤户相似度为0.66 ;
train : ⽤户记录数据集中的数据, 格式为: train= { user : [[item1, rating1], [item2, rating2], …], …… }
item_users : 将数据集中的数据转换为 物品_⽤户 的倒排表,这样做的原因是在计算⽤户相似度的时候,可以只计算看过相同电影的⽤户之间的相似度(没看过相同电影的⽤户相似度默认为 0 ),倒排表的形式为: item_users = { item : [user1, user2, …], ……}
k : 使⽤最相似的 k 个⽤户作推荐
n : 为⽤户推荐 n 部电影
1.
1. 加载数据
从数据集中读出数据,将数据以 { user : [[item1, rating1], [item2, rating2], …],……} 的形式存⼊ train 中,并整理成形如 { item : [user1, user2, …], ……} 的倒排表,存⼊ item_users 中。
1.
1. 计算相似度矩阵
基于⽤户的协同过滤算法的思想是有相似兴趣的⽤户(user)可能会喜欢相同的物品(item)。因此,计算⽤户的相似度成为该算法的关键步骤。实现过程中使⽤的相似度公式如下:
其中 N(u) 表⽰⽤户 u 看过的电影个数。
遍历 item_users ,统计每个⽤户看过的电影 item 的次数,同时遍历 item_users 中的 users ,先计算⽤户 u 和⽤户 v 看过相同电影的个数存在 W 中, 然后遍历 W ,使⽤上述公式计算⽤户 u 和⽤户 v 的相似度。
1.
1. 推荐
最后为⽤户 u 推荐,⾸先从 item_users 中获得⽤户 u 已经看过的电影,然后将⽤户按相似度排序,并取前 k 个⽤户,对这 k 个⽤户看过但⽤户 u 没有看过的电影计算加权评分和,计算公式为:⽤户相似度 * ⽤户对电影的评分。
1.
1. 代码运⾏结果
程序随机选择⼀位⽤户,根据和他最相似的 30 个⽤户,为其推荐 10 部电影,打印出推荐电影的 ID 和加权评分 [[电影ID, 加权评分],[电影ID,加权评分],……]。
[('8368', 18.62732007530837), ('68954', 18.56220733375745), ('6377', 17.15104837332028), ('58559', 15.323360864347197), ('8961', 14.729418859494816), ('56367', 14.609493525827729), ('5989', 14.579143788113251), ('2959', 14.574110342046716), ('318', 14.450046074595624), ('4963', 13.78373564820972)]
1. python 实现基于物品的协同过滤算法
与基于⽤户的协同过滤算法的算法流程类似区别之处:
1.
1. 计算物品相似矩阵
物品相似度的计算公式为:
其中N ( i ) 表⽰电影 i 被看过的次数,N ( i ) ⋂ N ( j ) 表⽰同时看过电影 i 和电影 j 的⽤户数。
具体计算如下:
⾸先遍历 train 变量 { user : [[item1, rating1], [item2, rating2], …],……} ,取出⽤户看过的电影列表,使⽤变量 i 遍历该⽤户看过的电影 ,对看过该电影的⽤户数(即变量 N(i) )加⼀,同时使⽤变量 j 遍历该⽤户看过的电影,如果 i 和 j 不同,则 W[i][j] 加⼀(此时W[i] [j]记录的是同时看过电影 i 和电影 j 的⽤户数)。
遍历 W 矩阵,对 W 中的每⼀个元素进⾏如下计算:得到的 W 矩阵就是物品之间的相似度矩阵。
2.2. 推荐
⾸先获得⽤户已经看过的电影列表,遍历该电影列表,对于⽤户看过的电影 i ,出与电影 i 最相似的前 k 个电影(对 W[i] 按照相似度排序),计算这 k 个电影各⾃的加权评分(rank):对rank按照评分倒序排序,取前 n 个推荐给⽤户即可。
2.3 实验结果展⽰
start loading data from ratings.csv
loading data successfully
start caculating similarity matrix ...
caculating similarity matrix successfully
start recommending items for user whose userId is 360
items recommeded for user whose userId is 360 :
[('2115', 12.599387984936264), ('2762', 12.390314342878924), ('1580', 10.178598234142198), ('2628',
8.72413463199201), ('1240', 8.69518606413058), ('2126', 8.503179297247316), ('1100', 7.644982642223123), ('1610', 7.503336083694675), ('1573', 7.458142040761965), ('2110', 6.956617382760688)]
Process finished with exit code 0
1. pytorch 复现 FM
提出了将特征进⾏交叉,以达到从特征中学习到更多有价值的信息。它的思想是为每个特征学习⼀个隐向量。使⽤ 数据集复现 FM 的过程如下:
1. 引⼊需要的包
2. 将⽤户数据读⼊ 将⽤户的 userId, gender, age, occupation, zipCode Label Encoding 编码
3. 读⼊⽤户评分数据 将数据 label encoding 编码
1. 然后完成 模块
2. 模型复现运⾏结果展⽰
1. 学习收获归纳总结
本周主要对传统推荐模型的发展脉络有了清晰地认识,对各种传统推荐模型的基本思想有了基本的了解,推荐算法在发现问题解决问题中不断演进,对传统的推荐模型进⾏了相关归纳总结:
( 1 ) 协同过滤算法。从物品相似度和⽤户相似度⾓度出发,协同过滤衍⽣出物品协同过滤( ItemCF ) 和⽤户协同过滤( UserCF )两种算法。为了使协同过滤能够更好地处理稀疏共现矩阵问题、增强模型的泛化能⼒,从协同过滤衍⽣出矩阵分解 模型( Matrix Factorization, MF ),并发展出矩阵分解的各分⽀模型。
( 2 )逻辑回归模型。与协同过滤仅利⽤⽤户和物品之间的显式或隐式反馈信息相⽐,逻辑回归能够利⽤和融合更多⽤户、物品及上下⽂特征。从 LR 模型衍⽣出的模型同样 “枝繁叶茂”,包括增强了⾮线性能⼒的⼤规模分⽚线性模型
( Large Scale Piece-wise Linear Model, LS-PLM ), 由逻辑回归发展出来的 FM 模型,以及与多种不同模型配合使⽤后的组合模型,等等。
( 3 ) 因⼦分解机模型。因⼦分解机在传统逻辑回归的基础上,加⼊了⼆阶部分,使模型具备了进⾏特征组合的能⼒。更进⼀步,在因⼦分解机基础上发展出来的域感知因⼦分解机( Field-aware Factorization Machine, FFM )则通过加⼊特征域的概念,进⼀步加强了因⼦分解机特征交叉的能⼒。
( 4 )组合模型。为了融合多个模型的优点,将不同模型组合使⽤是构建推荐模型常⽤的⽅法。Facebook 提出了 GBDT+LR[ 梯度提升决策树( Gradient Boosting Decision Tree )+逻辑回归 ]
1. 下周学习计划
1. 继续完成传统推荐模型的复现⼯作,加深对传统推荐模型的理解与认识。
2. 学习深度学习在推荐系统中的应⽤
3. 加强阅读相关⽂献论⽂
1. 相关代码展⽰ 基于⽤户的的协同过滤算法
import random
import operator
class UserBasedCF:
def __init__(self):
self.N = {} # number of items user interacted, N[u] = the number of items user u interacted
self.W = {} # similarity of user u and user v
self.item_users = {} # item_users = { item : [user1, user2, …], …… }
self.item_users = {} # item_users = { item : [user1, user2, …], …… }
# recommend n items from the k most similar users
self.k = 30
self.n = 10
def get_data(self, file_path):
"""
@description: load data from dataset
@file_path: path of dataset
"""
with open(file_path, 'r') as f:
for i, line in enumerate(f, 0):
if i != 0: # remove the title of the first line
line = line.strip('\n')
user, item, rating, timestamp = line.split(',')
self.item_users.setdefault(item, [])
self.item_users[item].append(user)
def similarity(self):
"""
@description: calculate similarity between user u and user v
"""
for item, users in self.item_users.items():
for u in users:
self.N.setdefault(u, 0)
self.N[u] += 1
for v in users:
if u != v:
self.W.setdefault(u, {})
self.W[u].setdefault(v, 0)
self.W[u][v] += 1 # number of items which both user u and user v have interacted
for u, user_cnts in self.W.items():
for v, cnt in user_cnts.items():
self.W[u][v] = self.W[u][v] / (self.N[u] * self.N[v]) ** 0.5 # similarity between user u and user v def recommendation(self, user):
"""
@description: recommend items for user
@param user : the user who is recommended, we call this user u
@return : items recommended for user u
"""
watched = [i[0] for i ain[user]] # items that user have interacted
rank = {}
for v, similar in sorted(self.W[user].items(), key=operator.itemgetter(1), reverse=True)[
0:self.k]: # order user v by similarity between user v and user u
for item_rating ain[v]: # items user v have interacted
if item_rating[0] not in watched: # item user hvae not interacted
rank.setdefault(item_rating[0], 0.)
rank[item_rating[0]] += similar * float(item_rating[1])
return sorted(rank.items(), key=operator.itemgetter(1), reverse=True)[0:self.n]
if __name__ == "__main__":
file_path = "ratings.csv"
userBasedCF = UserBasedCF()
<_data(file_path)
<_data(file_path)
userBasedCF.similarity()
user = random.sample(ain), 1)
rec = endation(user[0])
print(rec)
1.
1. 基于物品的的协同过滤算法
import random
import operator
class ItemBasedCF:
def __init__(self):
self.N = {} # number of item user have interacted
self.W = {} # similarity matrix to store similarity of item i and item j
# recommend n items from the k most similar to the items user have interacted
self.k = 30
self.n = 10
def get_data(self, file_path):
"""
@description: load data from file
@param file_path: path of file
"""
print('start loading data from ', file_path)
with open(file_path, "r") as f:
for i, line in enumerate(f, 0):
if i != 0: # remove the first line that is title
line = line.strip('\r')
user, item, rating, timestamp = line.split(',')
print('loading data successfully')
def similarity(self):
"""
@description: caculate similarity between item i and item j
"""
print('start caculating similarity matrix ...')
for user, item_ratings ain.items():
items = [x[0] for x in item_ratings] # items that user have interacted
for i in items:
self.N.setdefault(i, 0)
self.N[i] += 1 # number of users who have interacted item i
for j in items:
if i != j:
self.W.setdefault(i, {})
self.W[i].setdefault(j, 0)
self.W[i][j] += 1 # number of users who have interacted item i and item j
for i, j_cnt in self.W.items():
for j, cnt in j_cnt.items():
self.W[i][j] = self.W[i][j] / (self.N[i] * self.N[j]) ** 0.5 # similarity between item i and item j print('caculating similarity matrix successfully')
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论