介绍

下派一个任务,研究下推荐系统,貌似后面和电信搞一个类似电视视频内容推荐之类的项目.

基于流行度的推荐

这个推荐比较简单些,就是根据视频的得分来进行排序,排除掉当前用户已经看过的,剩下的再排序返回给用户就行.

好处是这是一个非常简单但是非常有效的算法,基本来说我们看视频都是根据播放量高、得分高进行播放。
坏处是有一个长尾效应,过于小众的基本不会推荐出来,看看京东,其实也有点类似这样~

关于视频的打分,这个可以根据一些特征工程来获得,比如用户点赞,收藏,喜欢,浏览,基于不同权重进行得分。
如果没有这些特征,可以手动构造这些视频的得分(不行可以抓豆瓣。。。)甚者直接根据用户的浏览记录进行排序就能上线。

对于长尾效应,可以运营分出几大类,根据类别再进行排序也是可以一定程度多了新的选择。
对于冷启动,这个咋说呢,一开始肯定都是没有数据的,可以先按照热度排个序上了线后续优化。

基于内容的推荐

这是一个基于内容特征进行推荐的方式。

比如说,张三看过言情、虐心电影A,那如果电影B也具有这种feature,就可以计算这些feature的相似度进行排序推荐给A。
至于特征有多少,emmm,可以打标签,比如导演,演员,简介tfidf,小清新,狗血之类。

另外如果基于深度学习的话,就要获得视频的向量,根据向量来进行排序推荐给A。

协同过滤的推荐

协同过滤推荐重点在于协同。这里可以分成两类:

  1. 基于用户的协同过滤
  2. 基于内容的协同过滤

啥意思呢,用户张三喜欢看A,B,D电视剧,用户李四喜欢看A,D,那么张三和李四是挺相似的,那么就可以推荐给李四用户B电视剧。这个就叫基于用户的协同过滤。

至于特征,也可以说张三和李四有其他特征,比如都是男的,年龄相仿,兴趣相仿,那就可以认为是同一类人,那推荐的内容也是可以类似的。

基于内容的呢,其实和上面的基于内容的推荐是挺类似的。

核心点是基于历史的数据进行来预测用户的相似程度来进行推荐内容,将人和人也关联到一起。

一种做法通过SVD(奇异值分解)来实现。
比如下面例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# -*- coding: utf8 -*-
#
import numpy as np
import pandas as pd
from scipy.sparse import csc_matrix
from scipy.sparse.linalg import svds

# value为用户对不同的item的喜欢程度
df = pd.DataFrame({"军事": [0, 10, 7], '言情': [10, 3, 0], '动漫': [5, 3, 0], '小说': [3, 5, 0]}, dtype='float64')
# 军事 言情 动漫 小说
# 0 0.0 10.0 5.0 3.0
# 1 10.0 3.0 3.0 5.0
# 2 7.0 0.0 0.0 0.0
# 可以看到user0喜欢言情和动漫,用户1、2喜欢军事

U, s, Vt = svds(csc_matrix(df), k=2) # K可以理解成用多少feature来进行表示,主要用于降维和减少稀疏性,超参数

matrix_new = U.dot(np.diag(s)).dot(Vt)
print(matrix_new)
# [[-0.1314746 , 9.7949323 , 5.08515349, 3.45149176],
# [10.28341738, 3.44206066, 2.81643619, 4.02672754],
# [ 6.55257518, -0.6978715 , 0.28978818, 1.53648395]] # 推荐顺序-> 军事,小说,动漫

# ################################ 推荐
item_user_matrix = matrix_new.transpose()
svd_df = pd.DataFrame(item_user_matrix, columns=['user0', 'user1', 'user2'], index=df.columns)
svd_df['user2'].sort_values(ascending=False)


# Out[18]:
# 军事 6.552575
# 小说 1.536484
# 动漫 0.289788
# 言情 -0.697871
# Name: 2, dtype: float64

# ###################################### 计算用户喜好相似度
def cos(vec1, vec2):
return vec1.dot(vec2) / np.linalg.norm(vec1) * np.linalg.norm(vec2)


for i in range(U.shape[0]):
for j in range(i + 1, U.shape[0]):
vec1 = U[i, :]
vec2 = U[j, :]
print(f'User{i}和User{j}的相似度:{cos(vec1, vec2)}')
# User0和User1的相似度:0.11017178104828797
# User0和User2的相似度:-0.11652231240752381
# User1和User2的相似度:0.28527719555421444

# 那同理,item之间的相似度也可以简单通过这种方式进行计算

更新

啦啦啦,现在也可以尝试其他做法,比如wide&deep,DSSM,DeepFM,pairwise,pointwise,具体看业务。

以后再有机会更新。

再次更新

前段时间面试了一个大佬,他之前在腾讯做过腾讯新闻个性化推荐,在2016~2019年期间,他的做法是这样的,
一共有三个graph,user,tag,article,将这三个进行关联到一起形成user-tag-article网络,基于这个网络进行随机游走,然后使用word2vec进行向量化,进行推荐。

虽然这种技术可能放到现在来说有点落伍了,但是对这种做法挺感兴趣,整体实现思路也并不难,所以尝试了下。

我将代码放到了graph word2vec embedding,感兴趣的话可以看看~