推荐系统(基于CB,CF,LR)

数据预处理

用户画像数据user_profile.data(10w条,5.79M):
userid, 性别, 年龄段, 收入段, 地域

物品元数据music_meta(75w条,117M):
itemid, 名称, 描述, 时长, 地域, 标签

用户行为数据user_watch_pref.sml(32w条,15M):
userid, itemid, 用户对该物品的收听时长, 时间(几点开始的行为)

首先,把3份数据融合到一份数据中,用户行为数据—用户画像—物品元数据:merge_base.data,通过执行pre_base_data / gen_base.py产生:
userid, itemid, 用户对该物品的收听时长, 时间, 性别, 年龄段, 收入段, 地域, 物品名称, 描述, 时长, 地域, 标签

具体是先把user_profile.data和music_meta各自的数据每行读入,按照userid或itemid为key,其余属性为value分别存入各自的字典user_profile_dict和item_info_dict中,再每行读入user_watch_pref.sml数据,在原有属性后拼接上user_profile_dict[userid]和item_info_dict[itemid]


在这里插入图片描述

CB算法

利用CB的思想就是基于物品的文本内容信息分词,算出物品-物品的相似矩阵,把一个物品所对应的相似物品及分数,以key-value形式入库。例如求itemA和itemB,itemA和itemB向量的各维是它们各自分出的token对应的score,然后利用余弦定理计算相似度,item之间的相似程度完全是基于从文本内容中所分出的词的重要性来决定的。

1.准备训练数据

先利用gen_cb_train.py对merge_base.data进行分词处理整理出训练数据cb_train.data,merge_base.data的每一行的物品元数据中包含name、desc和tags三处文本信息,对这三处进行中文分词,形成每个物品的token和score字典,key为token,value为score(这里要依据itemid去重,避免同一物品重复分词计算)。其中设置name、desc和tags各自的权重,以表示看重来自哪处的分词信息,来自name或desc或tags的token的score就乘上name或desc或tags的权重,如果token相同,则累加score值。分词的目的就是形成各item的向量,向量值就是token的累加score。最后输出每个物品(不同物品)的token,itemid和score信息:data / cb_train.data(部分内容如下)

Summer,6192809101,2.15185815052
Dance,6192809101,2.15185815052
MBC,6192809101,2.15185815052
李贞贤,6192809101,0.556404446485
现场版,6192809101,2.50212197736
明星,6192809101,0.33679786366
李贞贤,6192809101,2.00305600735
音乐,8915109101,0.331483455685

2.计算ii矩阵

然后通过cb_train.data数据,利用协同思想,得到ii矩阵,此时ii之间的相似度是根据item分出的token和score,也就是item的文本信息得来的,输出到data / cb.result:

  item tem score
000000228 0016709118 1.87106281814e-05
000000228 013700354 3.94388800644e-05
000000228 013800336 5.43847359064e-05
000000228 015600228 0.000165535837356
000000228 0211809186 0.000360792610514
000000228 022200321 0.000158684968794
000000228 029100335 0.000149225174654

协同求ii思想如下:


在这里插入图片描述

3.产生key-value键值数组

接着利用pre_data_for_cb / gen_reclist.py将data / cb.result的item item score的形式转变成key-value的list形式:具体是定义一个rec_dict字典,key为itemidA,value为与该itemidA相似的itemidB及score组成的列表,对每一个key即itemid对应的list按照元组元素的score值降序排列(粗排),取前MAX_RECLIST_SIZE个以防list过长。
即rec_dict = {( itemidA : [(itemid, score), (),…()] ), (itemidB : [(itemid, score), (),…()] ),… }
输出data / cb_reclist.redis形式如下:SET CB_itemid itemid:score_itemid:score

SET CB_6198809117 8135809223:0.285328_9080409315:0.256306
SET CB_6084009127 5358109115:0.291467_5520609203:0.25708

也就是说每个item都对应着一个与它相似的item列表,列表中越靠前的item与它越相似,这个相似程度完全是基于item的文本内容得来的。
“SET”是redis数据库的插入记录命令,将cb_reclist.redis的记录插入到redis数据库中

Item_Based CF算法

1.准备训练数据

还是利用data/merge_base.data,经过pre_data_for_cf / gen_cf_train.py整理出训练数据data/cf_train.data,形式为userid, itemid, score。这里score的计算与CB中的score不同,CB中是利用jieba对各item文本内容分词出的token和score,代表该token对于一个tiem只从文本内容上来说的权重值。而CF中的score是根据user对item的收听时长和item本身的时长得来的。比如从merge数据中会发现由于不同时间段的点击,同一个user对同一个物品产生多次行为:
userA itemA 40
userA itemA 70
userA itemA 50
itemA本身的时长是300s,那么该user对item的score= 160 / 900 ≈0.178
具体对merge数据的每一行,以userid_itemid为key,(收听时长,完整时长)为value,产生key_dict字典,将相同key的value追加进key_dict[key]列表中,遍历该字典,计算每个键值对的score,输出userid,itemid,score的形式得到训练数据data/cf_train.data:

0189c9fecdd47bb64720c23a960272d3,935400252,1.3
014e7a8f4544bcd156365d3f348399c2,068800255,1.21889952153
00af96daaf12d1afa11d102f9f98fc3b,405100213,0.0581395348837
00383d3536ce00ad469cb1c57946686a,732009535,1.5703125

2.计算ii矩阵
还是利用协同思想,得到ii矩阵,此时物品与物品的相似度是根据用户对item的行为score计算而来,输出数据到data / cf.result:

item item score
000000228	006900337	0.495383099617
000000228	237400301	0.4655287556
000000228	489600256	0.327370227556
000000228	880800319	0.6522021568
000000228	895300223	0.0654423912424

3.产生key-value键值数组

接着利用pre_data_for_cf / gen_reclist.py将data / cf.result的item item score的形式转变成key-value的list形式:具体是定义一个rec_dict字典,key为itemidA,value为与该itemidA相似的itemidB及score组成的列表,对每一个key即itemid对应的list按照元组元素的score值降序排列(粗排),取前MAX_RECLIST_SIZE个以防list过长。
即rec_dict = {( itemidA : [(itemid, score), (),…()] ), (itemidB : [(itemid, score), (),…()] ),… }
输出data / cf_reclist.redis形式如下:SET CF_itemid itemid:score_itemid:score

SET CF_6198809117 3293909128:0.787122
SET CF_6084009127 319300250:0.216058
SET CF_2842309275 794909681:0.708267_1749209326:0.705945

也就是说每个item都对应着一个与它相似的item列表,列表中越靠前的item与它越相似,这个相似程度完全是基于用户对物品的行为数据得来的。
“SET”是redis数据库的插入记录命令,将cf_reclist.redis的记录插入到redis数据库中

另外,以某一itemid为key,分别去检索由CB和CF得来的key-value列表,会发现CB里和该item相似的物品会多于CF的结果,可能CF推荐的效果更好,但物品少覆盖面就小,CB推荐的物品更加充分,覆盖面广。并且CB和CF列表里的score也是没有可比性的,一个是基于item文本内容作分词,一个是基于用户对item的行为,在各自的列表中都是把score值高的item排在前面。

LR算法

引入LR算法的目的是为CB和CF的结果列表作精排,因为通过CB和CF粗排(粗排的目的是取出各自比较优质即score高的物品入库,通过取前MAX_RECLIST_SIZE个物品,剩下不优质的就剔除掉)的物品的score不能在一起比较,这时就需要通过LR算法对CB和CF的物品计算score,然后作排序。也就是说,CB的结果是适合于新物品来作推荐的,CF的结果是基于长时间的行为来作推荐的,CF推荐的物品规模比CB要小很多很多,如果只考虑CF忽略CB,推荐就会丢失部分数据,如果只考虑CB忽略CF,那么一些优质的物品数据就不能被推荐出来。比如CB推荐出200个item,CF推荐出100个item,这些item内部作了排序(粗排),若将这300个item放在推荐引擎上,它们的score却不可比,于是通过LR对这300个item进行打分再作排序(精排)。
这里将样本引入one-hot编码,one-hot编码将每个状态位都看成一个特征。

1.产生指定格式的训练样本
训练数据:pre_data_for_rankmodel / gen_samples.py 将merge_base.data数据转换成所需的训练样本格式,将转换好格式的样本输出到data / sampes.data

具体做法是先利用浏览时间和总时长的比值计算出标签,标签为1代表用户喜欢该物品,0表示不喜欢;然后对样本其他特征转换成特征id:状态值的形式,user_fea_dict 字典存放用户id及其性别特征id:状态位和年龄特征id:状态位即{userid:[idx:1,idx:1] , …}用户特征的id转换具体如下图:有值的特征id,其状态位为1,大部分特征id对应的状态位为空,所以不必存储这些空值。


在这里插入图片描述

对于物品特征,先对物品name进行中文分词,切分出token和score列表,再为每个token进行id化生成对应的id,然后对id进行偏置得到最终的token_id。item_fea_dict 字典存放每个item名称及其token_id和score即{name:[(token1_id,score1),…] ,…}

最后对于merge数据的每一行,利用user_fea_dict和item_fea_dict生成训练格式的样本数据,如下:类别标签|性别|年龄|token:score

0 1:1 5:1 11402:2.64150609428 2016:2.39095350058 1168:2.13636036542 8088:1.99773092931 4257:1.61142664699
1 1:1 5:1 11402:2.64150609428 2016:2.39095350058 1168:2.13636036542 8088:1.99773092931 4257:1.61142664699
1 1:1 5:1 11402:2.64150609428 2016:2.39095350058 1168:2.13636036542 8088:1.99773092931 4257:1.61142664699
1 0:1 2:1 11402:2.64150609428 2016:2.39095350058 1168:2.13636036542 8088:1.99773092931 4257:1.61142664699
1 0:1 5:1 18555:5.97738375145 13789:3.97893913842

同时生成用户特征映射文件/data/user_feature.data,每一行是userid,feature:

000011f6b4dcae5a64d40dadeb51c880	1:1 2:1
007daf35156f3e800d9239eb42a3f2af	0:1 2:1
00370d83b51febe3e8ae395afa95c684	1:1 6:1
01463ded1475e488dfb4e6bc978780cb	0:1 2:1

物品特征映射文件data/item_feature.data,每一行是itemid,feature(token_id,score):

7168109339	540:2.98869187572 10466:2.85394275055 388:2.7262363446 16350:1.13912648309
025300356	540:2.98869187572 27468:2.8756955948 2843:2.79815686272 12830:1.93805233901
2966409314	22971:2.08573054848 27567:2.08573054848 11435:1.99246125048 10955:1.29167914725 7149:1.12789694951 7082:0.826173491012

物品id和name映射文件data/name_id.dict,每一行是itemid和item_name:

6198809117	夜色钢琴 《好久不见》钢琴版 高清
6084009127	未来的期待 斯琴格日乐大爱音乐节花絮
2842309275	陈瑞-造物弄人(发烧版)冒牌音乐 红日蓝月KTV推介
1048509232	新编赞美诗 赞美诗144首 安息圣日歌
5305109176	f(x) - Danger
812109631	佛教歌曲大全 佛教音乐序(印超上人专辑)

2.训练逻辑回归模型
训练模型:rankmodel / lr.py,利用转换好格式后的训练数据samples.data,进行逻辑回归训练,得到w和b,将其分别写入 model.w和model.b文件。

组装推荐系统

在这里插入图片描述
整个推荐系统中,一个用户正在浏览一个物品,我们需要拿到这个用户的userid和他浏览物品的itemid,这个itemid用于从数据库中召回与其相似的物品形成候选集合(来自CB和CF),然后利用训练好的模型结合这个用户的特征给候选集合打分,排序后产生最终的推荐列表。集合用户特征的目的是为了作个性化推荐,比如说我们有100个物品,张三来了和李四来了,我们给这两个人推荐的肯定是不一样的,那么这个模型该怎么构建,这里就需要用到用户的特征,结合物品的特征。具体步骤如下:
(1)解析请求:拿到当前用户的userid和其正浏览的物品req_itemid
(2)加载模型:加载已利用merge_base.data训练好的模型文件model.w,model.b
(3)检索候选集合,利用req_itemid去redis数据库里分别检索来自CB和CF的结果集,得到综合后的req_itemid->itemid itemid itemid推荐候选集合
(4)获得当前用户特征:利用userid和加载的user_feature.data获得当前用户特征字典u_fea_dict
(5)获得候选集合的物品特征:遍历候选集合里的itemid获得每个候选物品特征字典i_fea_dict
(6)打分排序(sigmoid):利用当前用户特征u_fea_dict和每个候选物品特征i_fea_dict组成预测样本x,与来自模型文件的w相乘后加b得到线性结果y,再嵌套进sigmoid函数得到预测值,此预测值模拟当前用户对该候选物品的喜爱程度,将所有候选物品和其得分追加进rec_list列表[(itemid,final_score)],按照每个元组的final_score降序排列
(7)Top-N截断:从rec_list中截取前10个推荐给当前用户
(8)数据包装:把rec_list中的itemid转换成item_name
(9)浏览器验证
http://master:9988/?userid=01463ded1475e488dfb4e6bc978780cb&itemid=741600204

Mahout 是一个由 Apache 开发的开源项目,通过 Mahout 可以快速地进行大数据处理。Mahout 中最常用的是协同过滤的推荐算法,而协同过滤推荐算法的应用最为广泛的是电影推荐系统。 电影推荐系统是一种基于用户兴趣的推荐系统,核心思想是根据用户的历史行为记录,如电影的评分等,通过算法分析出用户的喜好特征,结合电影的相关信息进行推荐。电影推荐系统不仅可以提高用户的使用体验,也可以带来商业价值。 基于 Mahout 实现协同过滤推荐算法的电影推荐系统,主要包括以下步骤: 1. 数据收集和预处理:系统需要收集用户对电影的行为数据,如观看历史、评分、评论等,同时还需要获取电影的相关信息,如电影类型、导演、演员等。收集到的数据需要进行清洗、筛选和预处理,以便后续分析和建模。 2. 特征提取和分析:基于收集到的数据,通过 Mahout 的特征提取和分析工具,可以对用户和电影进行特征提取和分析,分析用户的喜好特征和电影的相关特征,为推荐算法提供依据。 3. 推荐算法的选取和实现:根据数据特征和推荐需求,选择适合的推荐算法,并基于 Mahout 实现推荐算法。常用的推荐算法包括基于协同过滤的 CF(Collaborative Filtering)算法、基于内容过滤的 CB(Content-Based Filtering)算法、基于混合模型的混合过滤算法等。 4. 推荐结果的评估和优化:通过评估推荐结果,分析推荐算法的效果和准确率,并进行优化,以提高系统的推荐效果和用户满意度。 基于 Mahout 实现协同过滤推荐算法的电影推荐系统,可以有效地提高电影推荐的准确性和精度,并通过不断优化,为用户带来更好的使用体验和商业价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值