赞
踩
1.背景 根据物品或内容的元数据,发现物品或内容的相关性,然后基于用户以前的喜好记录推荐给用户相似的物品,如图所示:
上图给出了基于内容推荐的一个典型的例子,电影推荐系统,首先我们需要对电影的元数据有一个建模,这里只简单的描述了一下电影的类型;然后通过电影的元数据发现电影间的相似度,因为类型都是“爱情,浪漫”电影 A 和 C 被认为是相似的电影(当然,只根据类型是不够的,要得到更好的推荐,我们还可以考虑电影的导演,演员等等);最后实现推荐,对于用户 A,他喜欢看电影 A,那么系统就可以给他推荐类似的电影 C。
2.实现
上面在计算电影A和电影C的相似度时,通常可以用余弦相似度进行计算,但是当系统item百万级时,直接计算太耗时了,本文介绍fassi在基于内容推荐的使用(fassi我们经常在YouTubeDnn, DSSM等模型最后推荐topN的场景常见),本文基于moivelens的数据集实现,下面直接上代码:
2.1 电影数据处理
import re import os import numpy as np from utils.movielen_read import loadfile base_path = os.path.dirname(os.path.abspath(__file__)) + "/../../data/" def judge_year(year): """判断年份""" if year >= 2000: year_label = 1 elif year >= 1990 and year < 2000: year_label = 2 elif year >= 1980 and year < 1990: year_label = 3 elif year >= 1970 and year < 1980: year_label = 4 else: year_label = 0 return [year_label] def judge_genres(genres): """类型区分""" genres_lables = ["Action", "Adventure", "Animation", "Children's", "Comedy", "Crime", "Documentary", "Drama", "Fantasy", "Film-Noir", "Horror", "Musical", "Mystery", "Romance", "Sci-Fi", "Thriller", "War", "Western"] genres_list = np.zeros(len(genres_lables), dtype=int) for genre in genres: if genre in genres_lables: ind = genres_lables.index(genre) genres_list[ind] = 1 return list(genres_list) def item_features(): """商品特征矩阵""" item_feature = {} for line in loadfile(base_path + "ml-1m/movies.dat", encoding="ISO-8859-1"): arr = line.split("::") year = int(re.findall("\d{4}", arr[1])[0]) year_label = judge_year(year) genres = arr[2].split("|") genres_list = judge_genres(genres) item_feature_list = year_label + genres_list item_feature.setdefault(arr[0], item_feature_list) return item_feature
2.2 模型构建
import numpy as np import faiss from utils.item_util import item_features class FaissCB: def __init__(self): self.n_sim_movie = 10 def fit(self, item_matrix): num, vec_dim = item_matrix.shape # 创建索引 self.faiss_index = faiss.IndexFlatL2(vec_dim) # 使用欧式距离作为度量 # 添加数据 self.faiss_index.add(item_matrix) def predict(self, item_matrix): res_distance, res_index = self.faiss_index.search(item_matrix, self.n_sim_movie) print(res_index) if __name__ == '__main__': fcb = FaissCB() items = item_features() item_matrix = [] item_index_mapping = {} # {item_matrix_index: item_id} index = 0 for item_id, feature in items.items(): item_matrix.append(feature) item_index_mapping[index] = int(item_id) index += 1 item_matrix = np.array(item_matrix, dtype='float32') fcb.fit(item_matrix) fcb.predict(item_matrix)
代码:https://github.com/littlemesie/recommend-learning/tree/master/src/cb
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。