python音乐推荐系统_音乐推荐系统

音乐频道推荐业务,支持各个产品业务和策略。这里我先使用CB+CF+LR实现推荐部分,下面具体展开:

一、推荐系统流程图

a23493112655d811abd627074561c578.png

CB,CF算法在召回阶段使用,推荐出来的item是粗排的,利用LR算法,可以将CB,CF召回来的item进行精排,然后选择分数最高,给用户推荐出来。后续我们可以采用矩阵分解、聚类、深度学习算法来实现对候选集合的召回。

二、推荐系统思路详解

话不多说,这里先放上代码思路:

1、数据预处理(用户画像数据、物品元数据、用户行为数据)

2、召回(CB、CF算法)

3、LR训练模型的数据准备,即用户特征数据,物品特征数据

4、模型准备,即通过LR算法训练模型数据得到w,b

5、推荐系统流程:

(1)解析请求:userid,itemid

(2)加载模型:加载排序模型(model.w,model.b)

(3)检索候选集合:利用cb,cf去redis里面检索数据库,得到候选集合

(4)获取用户特征:userid

(5)获取物品特征:itemid

(6)打分(逻辑回归,深度学习),排序

(7)top-n过滤

(8)数据包装(itemid->name),返回

三、推荐系统实现

3.1、数据预处理

(1)用户画像数据:user_profile.data

userid,性别,年龄,收入,地域

a1a9633014182a1d87f36a45511bd5c5.png

(2)物品(音乐)元数据:music_metaitemid,name,desc,时长,地域,标签

cbba202fb761c54eaefa5190686ba4b9.png

(3)用户行为数据:user_watch_pref.sml

userid,itemid,该用户对该物品的收听时长,点击时间(小时)

50d594d30f56a262e9db61c113233abe.png

首先,将3份数据融合到一份数据中

执行python gen_base.py

1 #coding=utf-8

2

3 '''

4 总体思路:处理原始的数据:1、用户画像数据 2、物品元数据 3、用户行为数据5 把三类数据统一到一个文件里面,供后面cb、cf算法进行计算权重6 '''

7

8 importsys9

10 #找到三类原始数据文件,用户画像数据、物品元数据,用户行为数据

11 user_action_data = '../data/user_watch_pref.sml'

12 music_meta_data = '../data/music_meta'

13 user_profile_data = '../data/user_profile.data'

14

15 #将三类处理后的元数据放到新的文件里面,这里我们需要定一个文件名,路径

16 output_file = '../data/merge_base.data'

17

18 #将3份数据merge后的结果输出,供下游数据处理

19 ofile = open(output_file, 'w')20

21 #step 1. 处理物品元数据,将处理后的结果放入字典里面,key是itemid,value为物品对应的信息,为最后写入做准备

22 item_info_dict ={}23 with open(music_meta_data, 'r') as fd:24 for line infd:25 ss = line.strip().split('\001')26 if len(ss) != 6:27 continue

28 itemid, name, desc, total_timelen, location, tags =ss29 item_info_dict[itemid] = '\001'.join([name, desc, total_timelen, location, tags])30

31 #step 2. 处理用户画像数据,将处理后的结果放入字典里面,key是用户id,value是用户信息

32 user_profile_dict ={}33 with open(user_profile_data, 'r') as fd:34 for line infd:35 ss = line.strip().split(',')36 if len(ss) != 5:37 continue

38 userid, gender, age, salary, location =ss39 user_profile_dict[userid] = '\001'.join([gender, age, salary, location])40

41 #step 3. 写入最后的信息,将用户行为数据进行处理,把step1和step2得到的数据一并归纳在文件里面

42 with open(user_action_data, 'r') as fd:43 for line infd:44 ss = line.strip().split('\001')45 if len(ss) != 4:46 continue

47 userid, itemid, watch_len, hour =ss48

49 if userid not inuser_profile_dict:50 continue

51

52 if itemid not initem_info_dict:53 continue

54

55 ofile.write('\001'.join([userid, itemid, watch_len, hour, \56 user_profile_dict[userid], item_info_dict[itemid]]))57 ofile.write("\n")58

59 ofile.close()

得到类似下面数据merge_base.data

882eff0085c2dbf99e81da9a31452493.png

01e3fdf415107cd6046a07481fbed499^A6470209102^A1635^A21^A男^A36-45^A20000-100000^A内蒙古^A黄家驹1993演唱会高清视频^A^A1969^A^A演唱会

3.2、【召回】CB算法

(1)以token itemid score形式整理训练数据利用jieba分词,对item name进行中文分词

python gen_cb_train.py

1 #coding=utf-8

2

3 '''

4 总体思路:将初始化好的用户,物品,用户行为数据进行处理,目的是为了得到token,itemid,score,我们知道生成的数据里面的name,5 将itemName进行分词,得到tfidf权重,同时将desc进行分词,处理name和desc,我们在元数据中还有已经分类好的tags,tags已经切分好6 了没必要再次进行切分,只需要用idf词表查处权重即可,但是对于name、desc、tags这三个分词结果,我们对name的结果应该更加偏重一7 点,所以分别对这三类得出的分数再次进行分数权重划分,最后得到cb的初始数据8 '''

9

10 importsys11 sys.path.append('../')12 reload(sys)13 sys.setdefaultencoding('utf-8')14

15 importjieba16 importjieba.posseg17 importjieba.analyse18

19

20 #读入初始数据

21 input_file = "../data/merge_base.data"

22

23 #输出cb训练数据

24 output_file = '../data/cb_train.data'

25 ofile = open(output_file, 'w')26

27 #定义三类的权重分数

28 RATIO_FOR_NAME = 0.9

29 RATIO_FOR_DESC = 0.1

30 RATIO_FOR_TAGS = 0.05

31

32

33 #为tags读入idf权重值

34 idf_file = '../data/idf.txt'

35 idf_dict ={}36 with open(idf_file, 'r') as fd:37 for line infd:38 token, idf_score = line.strip().split(' ')39 idf_dict[token] =idf_score40

41 #开始处理初始数据

42 itemid_set =set()43 with open(input_file, 'r') as fd:44 for line infd:45 ss = line.strip().split('\001')46 #用户行为

47 userid =ss[0].strip()48 itemid = ss[1].strip()49 watch_len = ss[2].strip()50 hour = ss[3].strip()51 #用户画像

52 gender = ss[4].strip()53 age = ss[5].strip()54 salary = ss[6].strip()55 user_location = ss[7].strip()56 #物品元数据

57 name = ss[8].strip()58 desc = ss[9].strip()59 total_timelen = ss[10].strip()60 item_location = ss[11].strip()61 tags = ss[12].strip()62

63 #对item去重,相同的itemid不用再计算,因为都一样,这里用到continue特性,当不同的时候才继续执行下面的代码

64 if itemid not initemid_set:65 itemid_set.add(itemid)66 else:67 continue

68

69 #去掉重复后的itemid,然后我们进行分词,计算权重,放到字典里面

70 token_dict ={}71 #对name统计

72 for a in jieba.analyse.extract_tags(name, withWeight=True):73 token =a[0]74 score = float(a[1])75 token_dict[token] = score *RATIO_FOR_NAME76

77 #对desc进行分词,这里需要注意的是描述一般会含有name中的词,这里我们把有的词的分数进行相加,没有的放入

78 for a in jieba.analyse.extract_tags(desc, withWeight=True):79 token =a[0]80 score = float(a[1])81 if token intoken_dict:82 token_dict[token] += score *RATIO_FOR_DESC83 else:84 token_dict[token] = score *RATIO_FOR_DESC85

86 #对tags 进行分数计算

87 for tag in tags.strip().split(','):88 if tag not inidf_dict:89 continue

90 else:91 if tag intoken_dict:92 token_dict[tag] += float(idf_dict[tag]) *RATIO_FOR_TAGS93 else:94 token_dict[tag] = float(idf_dict[tag]) *RATIO_FOR_TAGS95

96 #循环遍历token_dict,输出toke,itemid,score

97 for k, v intoken_dict.items():98 token =k.strip()99 score =str(v)100 ofile.write(','.join([token, itemid, score]))101 ofile.write("\n")102

103

104 ofile.close()

得到如下数据:

04051d45ce7fadd43d3ff90f070a84e6.png

翻译,4090309101,0.561911164569(最后一个是一个不是传统的TF-IDF,因为分出的词在name,desc,tag里面他的重要性是不一样的)

(2)用协同过滤算法跑出item-item数据

相似的item配对,II矩阵的形成。相似度计算,我们要用到MapReduce的框架来进行,只要是用到shuffle阶段,对map出来的结果排序,reduce进行两两配对,这里就是主要的wordcount逻辑,主要说下注意

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值