00:00
我们截止到昨天为止,已经把这个离线和实时的整体框架都已经实现,而且代码都已经有实现了,所以大家到目前为止呢,已经应该有一个整体的。概念,或者说对整个项目应该心中已经是有数了,也知道他长什么样子,那接下来呢,我们其实今天要做的就是其他的一些事情。主要还有哪些事情呢?呃,就是我们需要考虑到具体应用当中,我们推荐可能不仅仅是这样的一些模型,这样的一些模式,我们仅仅是基于盈利模型去算一个预测评分,可能不仅仅是这么简单,那么我们常经常在实际项目当中还会遇到哪些问题呢?首先是一个冷启动的问题,这个其实我们在昨天在做实时系统联调的时候,大家已经发现这个问题了,我刚刚注册一个用户进来的时候啊,大家会看到其实那个实时推荐和离线推荐其实都没有,为什么呢?
01:05
因为我们的算法是基于盈余模型的,盈余模型它是一个协同过滤的推荐,它是需要以行为数据,评分数据作为基础的,我一个新的用户注册进来的时候,有评分吗?啊,什么东西都没有,所以一上来之后我们什么都看不到,那大家就会想到,那我如果要是想对这个用户友好一点,我总不能是这个电商网站新用户注册进来之后,首页是空白的,很多块是空着的,这个显然不好,对吧?对,所以我们可以有一些这个冷冷启动的一些预处理,怎么样处理呢?有,有很多网站它的做法其实就是对你一进来注册的时候,先有一个页面询问你,诶,你对什么东西感兴趣啊,让你去勾选,勾选一些标签,自然就会想到,如果用户勾选了标签,是不是就可以对按照这个兴趣的类别,然后把对应标签的那些商品给他推出来啊,这就是一个简单的冷启动的处理。
02:06
当然了,如果说用户他这个页面肯定不是强制的嘛,也可以跳过他也可以不选,那我们往往用到的就是比方说这个热门推荐,先有一个页面给用户推出来,对吧,或者说一些呃,做了一些比方说这个广告性质的竞价排名啊,把这些东西推到用户的首页,这都是实实际电商网站当中常用的一些冷启动,处理冷启动问题的手段,呃,这部分大家就是做一下了解,主要在业务系统里边就可以实现,跟我们推荐部分其实就关联不是特别大了,对吧。好,那接下来今天我们主要要讲的是其他形式的离线相似服务,呃,那么这些部分主要是应用在哪些环节呢?大家其实可以想到,在真实的电商系统里边。我们看到的推荐页面其实不仅仅是首页,我们前面讲的这个分区的混合啊,显示出来推荐列表其实都是在用户的那个首页里边看到的,那更多的情况是什么呢?其实应该是用户点了一个商品,我们往往能看到那个商品详情页里边还有相似推荐对吧?啊,或者说用户刚刚买了一个商品,然后你弹出来的那个确认框,或者说是其他的一个跳转页面的时候,还会显示说,诶,就是买了这个商品的用户还看了什么什么商品,对吧?啊,我猜你还喜欢还有哪些相似商品推荐,所以这里也是我们做推荐常见的一个场景,那这些推荐怎么样去做呢?当然这里边基于的就是跟商品的相似对吧?我们买了一个商品,或者说评价了一个商品之后,给他对应的这个相似商品做出推荐。
03:50
那我们有有哪些具体的方法可以做商品的相似推荐呢?我们就可以回忆起来,当时在讲这个推荐算法分类的时候。
04:01
我们的分类一大类是基于用户信息的啊,我们可以做用户画像,现在我们要基于商品,给商品做相似推荐,好像跟用户就用画像就没关系了,然后另外一大类基于商品信息的内容推荐,是不是就可以找到相似商品啊?我们找的是不是就是根据商品的内容信息,找到相似的商品,给用户去做出相应的推荐,哎,所以首先我们给大家讲的就是基于内容的相似推荐。这里大家就需要先去思考一下了,我们这里边能拿到的内容有哪些呢?对,这里其实大家会看到在呃,代码里边啊,大家可以看一眼data loader回顾一下这个商品信息,是啊,我们最好还是看这个。文件里边我们提取出来的格式,大家可以看一下啊,这里边我们拿到的有哪些呢?ID名称,然后这两个ID我们都知道,对我们做推荐没有什么用,对吧?然后图片这里图片啊,图片URL,然后还有分类,还有UGC标签,对这里边其实大家能想到我们能用起来的可能也只有这个分类信息和UGC标签了,呃,所以今天给大家做这个基于内容推荐这一部分呢,我们主要就基于UGC标签来做一个处理,那分类标签的话,这个其实比较简单,大家会想到,诶,我如果要是一开始用户选了对哪个分类感兴趣,那是不是这个可以直接根据标签去做匹配推荐,这个其实是更简单一些的方式,那我们这里边UGC这里呢,作为商品的信息,我们可能还要去做一个特征的提取和处理。
05:54
怎么样去从UGC标签里面提取商品的特征呢?
06:00
大家会想到这个用户打上的标签,其实其实没准的,你不知道他打什么样的东西,而且这里边每一个标签似乎也不能认为,就是说对于这一个商品而言,都是它非常重要的特征,对吧,因为有可能一个特征,你像这个好用啊,或者说这个电子产品啊,这就非常非常泛泛而谈的一个东西,这是不是跟这个商品的特征可能相关度。他的那个关键程度就没那么重。呃,大家一提到这个关键程度,可能就想起来,我们之前对给大家讲到关于这个特征工程特征处理的时候,讲过一个关键词提取的算法叫做。T fidf,大家还有印象吧,所以我们在这里对于商品的UGC标签,我们可以把每一个商品它所有的标签就当成我们那里的这个文本文档来进行处理,那对应的这里边具体的每一个标签是不是就相当于是文档里边的一个词汇啊,我们现在想看的其实就是一个词汇,在这个商品它所有这个标签里边对它的关键程度是多少,那么这个关键程度是不是就可以代表商品的一个特征啊?
07:26
它在这个维度上的一个特征,所以这其实就是我们的一个基本思想,好,那接下来我们就在recommend下边去新建一个模块。这个模块我们叫做呃,内容推荐啊,Content recommend。这样一个新的推荐模块,我们把它创建出来,首先要考虑它的依赖,这个基于内容的推荐,大家想一想,我需要什么样的东西呢?
08:04
哦,大家会想到整体的处理流程,我们可以因为它也是离线的一个相似推荐,对吧,我可以借鉴一下当时的,呃,离线这一部分它的。我们看一下他当时的这个po文件,我们用到了哪些依赖?首先这里边有一个g plus g plus当时我们说是干什么的来着,是做一个对矩矩阵运算,我们当时用它,它是一个线性代数的库,里边有一个叫double matricx的一个一个呃类,对吧,我们把一个数组转成double matrix,就可以很容易的算他的那个余弦相似度了,那么现在我们需要它吗?呃,大家觉得不需要单想我们这个目的是要最后做一个什么推荐。是不是还是一个相似推荐?
09:02
那我们的相似度怎么算?那我们的想法,哎,T fidf,我们得到的应该可以认为是它的一个特征向量,是不是大家想一想,我们得到的那一步应该对应到当时的这个离线推线,这里是不是应该拿到的是商品特征向量,就是这一步啊,Product features啊,那来想我们拿到这个product features之后怎么做呢?哎,是不是还是两两配对去做这个余弦相似度计算啊,那其实下边的这个过程,我们甚至都可以直接照抄之前这个。离线推荐这一部分,所以那我们是不是一样应该,如果就照抄这一部分代码的话,一样应该把它转换成一个double matrix,然后用我们当时的这个实现把它做一下就可以了啊,所以这部分我们就想着就简单实现就照抄了啊,所以g plus是不是也需要,所以这部分也是需要的,然后我们一个一个看啊,Spark需要吗?
10:09
Spark扣啊,对对,这个肯定需要这个,我们既然是用这个Spark去做这个离线的这个数据处理嘛,当然是需要的,MLLA啊,当然也是需要的啊,这是基本的东西,诶那大家想到这个CSPACQ是需要的,对吧?ML lab为什么需要呢?我们当时在离线这一部分ML lab是用的as吗?那现在的这个基于内容也需要ML吗?因为我们用到了t fidf,那t fidf如果我们不想手写的话,那也得调库,这个库是不是也在ML lab里边啊,所以我们照样还是要它,呃,那后边的sky library mongo相关的东西是不是该需要的都需要,所以这一部分就很简单了,最后我们的结论是不是直接照抄,所有的原封不动都拿过来啊,该有的都有,而且我们用到的这里边也都有了啊,没有别的了,所以就把它全部拿过来,好,我把它复制过来,呃,然后接下来在。
11:18
我们的目录下边把对应的这个日志配置copy过来,这些都是常规操作,然后我们可以把这个改一个名字叫skyla,呃,那大家会想到我们在下边还是新建一个。是不是object呀,单对象啊,然后名字就叫做com点点content.content recommender。创建出来,按照我们之前的这个思路,首先是考察样例类,那大家想一想,我们这里边需要哪些样例类呢?
12:04
同样我们就是对应这个当时做的这个基于盈运模型的离线推荐,大家看一看哪些需要,我们直接抄过来就可以了。嗯,大家看当时的这个样例类,我们首先定义了一个product RA,就是评分的那个样例类,我们这里需要吗?对,因为当时我们是基于行为数据去做应为模型,呃,协同过滤推荐的,所以它是需要基于行为行为数据评分数据的,我们这里基于的是什么?对基于物品的信息,那其实不需要RA需要的是需要的是不是product信息啊,所以我们这里边应该应该创建的是product样梨类啊,那我把这个product copy过来。大家会看到这个就是代码都是一大抄,但是我们得知道该抄什么,看你会抄不会抄,自己要想清楚,思路清楚就可以,呃,对,好,接下来大家看到这个mongo的配置样例类也需要,对吧?那么下面这几项要吗?
13:12
我们想到最后推荐出来的内容,如果要写到网购里面去的话,标准的格式是不是我们最后拿到的,是不是就相当于是一个相似度列表啊。我们得到一个相似推荐,是不是就相当于是一个商品ID对应着他的一个相似度列表,这个列表是不是又代表了推荐的优先级,推荐的力度,所以最后我们得到的是不是跟离线推荐的最后一步这个相似度列表是一样的呀,所以我们就直接借鉴这边的写法啊呃,当然大家也可以把这一部分就是提取到一个公共的类,我们不需要就。就可以把它相当于做一个提取啊,抽取到外边去,那大家会想到这里边用户的推荐列表还需要吗?对,这就不需要了,现在我们所有的内容都是基于商品来做的,商品的相似,有商品的相似就可以了,呃,这就是我们前面呃样例类的一些定义,然后接下来进入到object里边来的话,我们先定义一些常量,同样还是可以先考察一下,在之前离线推荐这一部分啊,因为模型这一部分我们定义了哪些常量呢?哎,这里因为它要用评分数据,所以用到了RA,那我们这里面用的可能不是RA,对,而是product,对吧?我们这里把这个copy过来。
14:42
除了product之外,我们可能还需要用到什么呢?大家想一想,在这里诶大家看我还定义了两个叫user Rex和product re的两个表,这是我们最后要写进去的推荐列表和相似度列表,我这里是不是不需要这个推荐列表,但是需要相似度列表啊呃,相似度列表就相当于是我们这一个整体算法这一个程序的最后的输出,所以我得把它定义出来,那那这个表名不应该一样,要不然就把之前覆盖了,对吧?不同算法应该给不同的表名,我这里边叫做content。
15:22
Best product recommend。呃,那同样这里就叫做content product Rex就可以了。把这个表名定义出来。接下来就是。入口函数,Main函数,呃,里边呢,我们还是照着这边来考察一下,一开始做这些配置,该有的配置是不是不变,该有的还得有,然后创建SPA Spark session,这是是一样的流程,这些都没什么问题啊,然后该引的包引进来,构建这样的定义,这样的一个mobile con,这前面的几步都一样,好,我直接把它copy过来吧。
16:06
我先把它取消掉,呃,那么大家会看到我这里边需要改什么呢?呃,是不是这个APP name你得改一下,对,这里改成recommend,然后下边把这个SPA。Enro。好,这一步先做完,接下来我们就需要载入数据做预处理了,常规操作啊呃,那之前在这个基于营运模型的这一部分呢,我们是加载了RA数据,评分数据,那这里我们要加载的其实是对,其实是商品数据。而且大家会想到我们最后想要得到的是一个什么样的形式呢?我们感兴趣的,现在我们感兴趣的其实只有。
17:00
是不是只有那个标签信息啊,就是用户生成的那个标签信息啊。所以我这里边最后把它处理成叫做一个product tax,呃,那当然这里边我们就涉及到一个问题,你最后是把它转成RDD还是data frame,诶,这里边我们后边调用这个ML live方法的时候,我们都用data frame的那一套API,那一套接口,那么这里边我们主要是都转成data frame text data frame,那么它的方式是不是就是点read呀?哎,从我们mango里边去做数据的加载option。大家再稍微回回忆一下这些项目应该写什么啊,Mongo里边拿到uri对不对?这个大家应该写几次就都已经很熟了,然后后边需要去定义collection,注意这里的应该是哪个,应该是product对吧?Product,诶,Product诶,我们前面没有定义哦,定义的叫go。
18:17
我们把它加载进来,然后form com.mango DB Spark circle,然后点load把它加载进来就完事,对吧?呃,这里边我们加载进来之后还要做一下处理,首先把它作为我们定义好的样例类product,呃,先转换过来,对吧?然后接下来大家会想到我需要哪几个具体的字段呢?我可能只需要里边本身是包含了product ID name,还有这个图片,URL,还有种类,还有这个types,我们是不是只要types啊,啊,对,当然我如果要是说大家还想去做别的东西做处理的话,这个种类也可以去做处理,对吧?我们这里只对这个text做处理,嗯,好,那我们主要用到的数据其实就是tax,然后为了我们。
19:18
方便看到他其过其他的相关信息,这个types是要的,Product ID肯定也是需要的,对吧,这两个肯定是需要的,然后为了我们更直观的看到它的别的信息,我们把name也保存下来,就是我们方便自己来查看啊,所以这里做一个map处理,把它每一个元素转换成什么呢?我们把它转换成一个三元组的形式,就是一个是product ID,这是第一个对吧?呃,然后我们说name也保留下来吧,还有一个就是我们想要的text,对,这里边text在做另外一个处理,就是我们的text本身是按什么做的分词呢?对,大家看到在这个data loader里面,这里可以看到它是按照竖线做的分词,而后边如果我们调用这个,呃,T fidf,它直接可以用到一个分词器,它默认的分词是什么呢?
20:28
分词的这个方式是什么呢?是空格,因为大家想到这个在英文里边正常来讲就是空格,分格的更是我们的词汇对吧?所以我们这里边也可以做一个预处理,就把它的分隔符都换成呃,对,都换换成space,呃,这里面大家可以先按照竖线把它lit出来,然后再用空格去做一个连接,这是这是可以的,对吧?对,或者我也可以用另外更简单粗暴的一个方法,对,大家会想到就是可以是不是对里边的每一个字符直接做一个转换处理啊,如果说它等于竖线的话,那么就是一个空格,Else c,大家能看懂这种写法吗?呃,这个其实很简单,其实就是说对,其实就是replace的一个实现,对不对?大家想是不是就是这里边。
21:28
挨个去查我们当前的字符,如果说它等于竖线,把它换成空格,如果不是的话,保留原始的字符是不是就完事了?这其实就是replace的一个简单实现。好,那接下来。已经得到了这样的一个三元组,我们最后因为最后处理还是一个data frame,我们还是把它转成to data frame,把这个名称也给它命名出来,因为大家想到这个你如果不给名称的话,上面直接弄出来是不是就都是下划线一,下划线二这样的东西啊,这里边我们叫product ID。
22:07
Name。然后还有一个text,把这个每一列的这个字段名称写出来,呃,当然了,我们最后性能考虑可以加一个点catch缓存起来,放到这个持久化的内存,对吧,有了这个基本的数据之后。我们是不是就可以从里边应用一些算法,我们这里边用到了TFIDF去提取,从基本信息里边去提取商品的特征向量,然后拿到特征向量之后,是不是就可以去呃做这个相似度的计算,然后把它存储到芒果DB里面去了,那这其实接下来的这个过程大家应该都知道了啊todo,我们写一个todo啊,用TF。
23:00
IDF。提取商品特征向量,呃,这里我们先把它给一个product features,先把它写在这里吧,先给一个now,然后大家会想到这里边提取出来之后,我们做的操作是不是跟这篇完全一样啊?大家看这个第三步,拿到了这个product features之后,这我们是直接从这个model里面就把它拿出来了,我们这里可能是还要做很多很多计算转换t fidf,拿到这个product features之后,假如我们转换成跟之前这个一样的格式,是不是后边就直接照抄啊?大家想想是不是这样,直接按照这个来,你去自己跟自己做一个笛卡耳机,然后过滤,然后哎算余弦相似度,还是用这个cos same这个函数来做一个计算,最后得到的结果是不是写到Mo里面去啊,所以接下来这一部分几乎就可以全部啊照单全抄,我们就如果犯大家比较懒的话,我直接就把这个全copy过来好了。
24:13
呃,那这一部分大家会看到这里还报错,那是因为这个product features还没东西,所以他不能去调用它下面的方法我们要改哪个东西呢?写的这个表得改这个表我们现在叫做content product re,这个大家先改过来,然后还有一个这个求余弦相似度的函数,是不是也是应该先把它拿过来啊?好,我们把它实现在这里,把这个g plus下边的double matricx引入,所以大家看就是如果我们只是想把这个流程打通,把这个算法实现的话,我们后边都可以直接照抄,那这个过程大家再复习一下我们是怎么做的,就是拿到特征向量之后对两两这个做笛卡尔机,这这里大家就要注意了,我这里边是不是这个必须得是一个RDD啊,对吧?啊,这个笛卡尔机的这个操作,这是针对RDD来说的,所以两两配对,然后接下来做一个filter,要求对,把自己过滤掉,然后接下来算余弦相似度,调用这个函数得到的结果我们包装成一个product ID,对,后边跟上一个元组。
25:27
这是另外一个product ID加上它的那个相似度的那个值,呃,我们最后呢,选取相似度的值大于0.4的,然后group I k,根据前面这个ID来做分组,得到的后面就是一个列表了,对不对?然后我们把它转换成想要的product RA的这种形式,呃,这里边我们还有这个呃,With操作啊,然后再对吧,把它转换成这个recommendation的形式,最后调用data frame的writer,把它写入到mango里面去就可以了。
26:00
这里还报错,我们看着不舒服的话,先住掉啊,等会再把它打开就好了。
我来说两句