00:00
部分是基于影语义模型的协同过滤,那我们先回顾一下整体流程,我们要做什么?整体流程其实非常简单,引语义模型,我们要调用这个ars算法去求解引语义模型,对吧?最后得到的是不是就是把一个平分矩阵分解成两个小矩阵?那么这两个矩阵就代表了。用户的特征和商品的特征对吧,大家回忆一下啊,一个评分矩阵R分解成两个矩阵,特征矩阵P和Q啊,那么我们只要把这两个特征矩阵算出来,接下来就可以得到什么呢?是不是把这两个矩阵一乘,乘回去就又可以得到一个预测评分矩阵啊,因为原始的评分这个R评分矩阵应该是一个稀疏矩阵,而我们分解之后再乘回去,得到的就是一个稠密的了,里边原先没有平分过的地方也就填充了一个评分值,这就代表了用户对对应商品的预测评分,我们根据这个预测评分的评分高低,是不是就可以得到给这个用户应该推荐哪些商品啊?呃评分预测评分越高的商品就越应该推荐,所以这就是我们整体的一个呃推荐思路。
01:24
那当然了,具体在做这个推荐的过程当中分为哪几步呢?我们可能首先需要用这个user ID和product ID做一个笛卡机,产生对他们这样的一个二元的元组,对吧?一个user对应的一个商品,然后通过模型把这个元组传进去,就可以预测它对应的评分,那前提是要把这个模型先训练出来啊,前面我们就要去训练这个模型,那么得到预测评分之后,根据这个分值进行排序,我们返回分值最大的前K个商品,就可以得到当前用户的推荐列表,那这就是整体思路,最后我们把这个数据再保存到mongo里边,我们定义一个叫user Rex,就是user recommendation,对吧,这样的一个表里边让业务系统去读取,就可以实时的显示出来了啊,所以这是。
02:24
做这个基于引语翼模型离线推荐的整体思路,我们这一部分内容除了这个推荐列表之外,还有一个副产品,当时给大家讲过,还有一个什么副产品呢?大家回忆一下啊,呃,就是除了这一部分之外呢,还有一个所谓的商品相似度矩阵,对吧?那么这一部分是做什么事情呢?对,主要是为后边做实时推荐来打下基础,因为大家知道如果要去实时的给用户有一个推荐的信息,有一个反馈的话,你如果现场去算那些商品的相似,然后给他做推荐,这显然是来不及的,那我们怎么样去呃,能够更好的提升实时性的提前计算,因为大家想到在呃,我们这种商品信息相对稳定的业务应用场景里边,我们是不是可以按照之前我们得到的信息,先把他们的相似度算出来,放在这里实时推荐系统直接用就可以了啊,这样的话就会更快,所以我们在做完盈余模型求解出来之后,已经拿到了商品的特征。
03:38
每个商品的特征向量都拿到了,那是不是基于特征向量就可以算他们两两之间的相似度啊?当时我们定义了这个余弦相似度,大家用这个余弦相似度的计算公式就可以算出任意两个商品的相似度,把它也保存下来,为之后的实时推荐打下基础啊。这是我们两个主要的输出,另外还有一个,还有一部分内容是什么呢?那就是模型评估和参数选取,大家会想到前面我们讲到做这个模型。
04:12
训练的时候我们用到的是as算法,它里边其实是有很多参数的,那那些参数怎么去做选取呢?肯定不能直接拍脑袋,拍脑袋想,所以后边还有一部分内容给大家讲一讲模型的评估和参数选取。好那。接下来这个过程大家会看到啊,我们最后想要得到的这个推荐列表的数据结构是怎么样保存的呢?其实就是一个user。有一个user ID对吧?把这个作为K,它是不是后面就应该跟着一个推荐列表啊,这个推荐列表又是怎么样的一个存储格式呢?呃,那就是对应的一个product,然后一个那个推荐分数,一个product,一个推荐分数构成的这样的一个列表,这是不是就是我们最后的能够拿到的用户的推荐列表啊?呃,这就是这样的一个存储结构。
05:12
好了,我们接下来就具体在代码里边做一个实现,还是先重新在recommendation下边去,Recommend下边创建一个子模块,呃,这一部分,呃,为了跟后边的实时分开,我这里边就跟文档里边写的一样,直接叫offline recommendation了recommend了,大家如果要是想做一些别的命名的话,按照自己的需要去做命名啊,这个是基于英语一模型的协同过滤。好,我们还是把它对应的目录放在recommend下边。创建这样的一个子模块,首先看po文件添加依赖啊,大家想一想,这一次我们还需要什么样的依赖呢?那还是回顾一下之前的这个po文件吧,统计这里我们需要的是Spark,这里要吗?对,应该也要,这个肯定要统计里边要我们这里边做这个,呃,离线的协同过滤推荐肯定也要嘛,Spark相关的,呃,这个应用肯定是需要的,Spark CQ需要吗?
06:28
那里边我们往里边写入数据,读取数据的时候,也是用到了spaq相关的组件,对不对,然后还有这个sky library是不是也要啊,跟mango的连接和mango的驱动要吗?全要,另外除了这些之外,还有没有新增的东西?啊,大家想到了对我们这里边要做盈语翼模型的推荐,那是不是得用机器学习相关的东西啊,Arrs算法显然是机器学习算里边的算法,我们需要用到Spark的MLLA,除了这个之外,另外再给大家引入一个,呃,大家可以看到文档里边啊,引入一个叫做j plus的一个包啊,这个我们之前做版本控制的时候,是不是也把它加进去了啊?这个东西是做什么的?主要是呃,这是Java的一个矩阵运算的库,就是线性代数相关的一些运算的库,把它加进来之后,我们后边再做向量之间的。
07:30
余弦相似度计算的时候是不是就会很方便啊,所以主要是为了这个考虑啊,呃,所以大家看到这里边SPASPACQ,还有ML live,把这两个多多加进来,别的还是一样。好,大家如果已经了解清楚的话,我就把这个copy过来。好,这个应该没有什么问题了,对吧?呃,接下来我们就可以去写代码了,在写代码之前还是啊,先把这个log for g的日志配置文件copy过来。
08:16
呃,然后我们可以把这个原文件目录改一个名称,在下边去new一个。我们是不是还应该有一个?Object呀,还是一个单例对象,因为大家想到这里边你去做离线的引语模型,协同过滤推荐,是不是别的地方也不会去创建它的,就是基于这个类去创建它的对象,也是我们只要运行的时候跑一遍是不是就完事啊,所以这里还是一个单立对象啊,这里边还是加上它的包名艾特硅谷点,呃,这里边我们就不一样,就叫offline吧。大家可以自定义。
09:01
Recommend。进入到呃,具体的这个代码实现里边来,首先还是先看样例类。大家注意,这里边我们的样例类需要什么呢?跟统计推荐相比,一开始RA要不要?大家想一想,在做这个基于云语音模型协同过滤推荐的时候,主要的数据来源是哪里?是不是就是行为数据,就是评分数据啊。基于英语义模型的协同过滤,基本的数据是不是还是基于评分数据去做推荐的,所以RA是不是必不可少啊,所以这里边还是要把RA放进来的,那mongo con这个要吗?啊,对,这个当然了,Mango相关的操作这两个都要。
10:00
先把它放进来,然后接下来除了这个呃,基本的数据和mango的配置之外,我们这里还需要多定义几个样例类,比方说什么呢?这就是大家考虑到在前面我们讲到的时候,最后存储的过程当中,是不是应该把它存成这样的形式,一个用户对应一个列表,这是我们最后的这个推荐列表的格式对不对?然后每一个列表里边它又包括两个元素,是不是应该有一个呃,Product ID,然后有一个对应的分数啊,推荐分数,所以我们可以把这个包装成一个样例类啊,到时候我们写的时候就会方便一些,His class。我们定义一个叫做。Recommendation的。标准推荐对象啊。
11:02
呃,那么这里面我们需要什么东西呢?这个recommendation是不是就是需要两个元素啊,一个是。Product ID还有一个是。啊,就是对应的那个评分score啊,这里面product ID。应该是一个int数据类型,那么score的话。按照我们之前的写法,是不是就是一个double类型啊啊,我先把它定义出来,然后进一步去定义。用户的推荐列表。大家想一下这个用户的推荐列表,我们就叫做user吧。它是一个什么样的状态,是不是前面有一个user ID,后边跟着的就是recommendation的一个列表啊,所以我们这里边在样例类里边把它定义出来user ID。
12:08
Inter。后边是不是跟着一个ras,它是什么结构呢?应该是一个sequence啊里边它的。类型是一个recommendation类型,所以这是我们提前定义好的这些。呃,当然如果大家看到这个代,就是文文档里边的这个代码实现,下面还定义了一个叫做product RA,这主要是考虑什么呢?我们之后是不是还有一个除了用户推荐列表之外,还有一个相似度列表啊,那相似度列表怎么去存储呢?诶,我们会想到这本身我们说的时候这是一个相似度矩阵。是一个,就是任意两两商品之间的一个相似度的一个一个矩阵,那么我们存储的时候用什么方式存呢?
13:02
一个,呃,对,大家会想到我们要存储的时候还是方便到时候查询,考虑到这个,那我们是不是应该根据一个商品的product ID,然后给他一个对相似度的列表,那具体到每一个相似度列表里面的元素,是不是还是一个product ID后面跟着一个相似度的score,那还是一个recommendation对象,所以我们一样可以应用这样的模式去定义啊。定义,呃,商品相似。度列表,我们还是定义出来plus定义一个叫做products,这里边一开始就不是user ID了,变成了product ID。
14:04
同样是一个int类型,后边是不是跟着的还是一个rax,然后是一个recommendation的sequence啊,一个列表对不对?所以我们先把这些样例类定义好啊,呃,定义好了这些之后进入到呃主体内容来,根据之前的这种呃,我们的这些套路,还是先定义一些常量,一些表明吧,这里边用到了RA,那是不是还要把这个RA copy过来,这部分是不会少的啊,接下来我们定义一下,在这个程序里边需要写入到mango哪两张表里边呢?是不是有一个用户的推荐列表,还有一个商品的相似度列表啊,啊,就是这两部分,所以。定义一个用户推荐列表,我们就叫user。
15:01
我们就叫X吧。等于。呃,这里面名字命名一样有ras。同样,我们可以定义一个商品的列表,Product。S,诶,上面好像写错了啊,CS啊。Product把它写进来,呃,另外我们再定义一个,呃,就是本身这个列表总共最大有多长呢?我们推荐多少个呢?这应该也是一个常量定义,所以这里可以定义一个user推荐列表,Max长度啊,Max recommendation。
16:02
我们这里举一个例子,比方说20个吧,最后推荐出来的列表最大返回20个,那是不是我们根据它的评分高低做一个排序,选取前20个返回就完事啊,就是这样的一个过程。好,有了这些之后,接下来我们定义入口方法,Main函数,那首先会想到一开始的过程还是跟之前一样,对不对?呃,做一个一些基本的配置项,定义一些基本的配置项,创建Spark conig,然后Spark session,该引入的东西引入,定义这样的一个mango conig,这些过程是不是一样啊?所以我们已经熟悉的话,这里就不一一实现了,这里直接把它copy过来,呃,我先直接cancel掉,因为这里边有一些东西我们不需要去完全引入好SPA figure。Spark session,好,这里注意con里边每一项是不是都要用到呢?
17:05
SPA course。这里我们还是用local芯,然后mongo UI是不是也要用到啊,跟mongo相关的东西,Mango DB都要用到,没问题啊,都保留,然后接下来SPA这这里边是不是需要改一下。APP内啊,这里改成offline,然后接下来创建SPA session,这个都没什么问题,然后创建mongo con,接下来大家想是不是要加载数据了。呃,加载数据这一步呢,我们前面在这个统计推荐模块里边,我们把它是转成了data frame,这里呢,我们希望把它转成RDD,因为最后我们调用的as算法点train要传入的那个训练数据,我们调用的方法里面要求的是RDD,所以这里边做一个RDD的转换RA。
18:06
RDD。那么它用到的是什么方法呢?SPA session的是不是还是RAID方法?啊,对,就这一部分,如果我们已经都熟悉的话,把这一部分是不是直接复制过来就可以了,至少是不是可以做到哪一步啊,是不是做到as都一样啊,对吧,把它漏进来,然后as RA,哎,这里边我们就不用这个统计模块里边定义好的这个RA和对应的这个表格了,我们用自己这里定义好的是不是一样啊好。然后已经进来之后,把它转换成一个RDD,然后还要做一个。Map转化,我们希望把它转化成什么格式呢?
19:00
呃,这里面的每一个RA,我们希望把它转化成,哎,就是对应的user ID,然后product ID,还有SC这样的一个三元组的格式,它对应到我们最后的应用的那个数据格式里边去,其实是als里边。就在我们的这个ML lab里边定义好的一个RA数据类型,一个数据类,那么这里边我先只是做这样的一个转换啊,ra.user ID ra.product ID点呃,ra.score对吧,我们先把这三个元组先三元组先拿出来,呃,然后做了这样一个简单转换之后,后边为了出于性能考虑,可以加一个点catch持久化在内存里边对吧?呃,方便我们后边避免这个RDD重复计算。
20:04
做了这些操作之后,接下来就还还有一个需要去做的事情,去做什么呢?呃,提取出用户的数据集,就所有的用户,还有所有的商品,对吧?呃,到时候我们是不是要拿这两个去做迪卡机,然后去做预测评分的。那么所有的用户当然就是user ID了,这个从哪里去拿呢?对,是不是从这个RARD里边直接拿出来就可以了呀,而且大家会想到,呃,RARDD里边我们是不是只关心RARDD里边有的user ID没有的我们也不关心对吧?呃,预测评分也也不会去,你既然没有的话,那肯定就什么数据都没有了,那就没有办法去预测评分了,所以这里边我们去。呃,提取出。
21:03
用户和呃,商品的。呃,数据集吧,所有用户。我们用到的其实就是。呃,最后拿出来也是一个RDD啊,U的RDD,那么它应该就从RARDD里边直接去取,是不是第一个元素就可以了,大家看好,它有可能有重复对不对?大家已经想到了,这里面有一个问题,有可能有重复,那我们是不是可以直接调一个对distinct去做一个去重就完事了啊,这是我们能够想到的啊,接下来同样还有一个product r DD。等于RARDD里边,这里我们map取什么?诶,这这个写法大家知道是吧?呃,元组取元组里面元素的写法是不是可以用下划线,然后对它的下划线二就表示它里边的第二个元素对吧?呃,那么这里边我们拿到的是product ID,同样做一个distinct操作去重就可以了。
22:19
有了这些东西之后,接下来是不是就是我们的核心内容了,土do对吧,可以去,呃,就是我们叫核心。计算过程这里边又分为三步,第一步应该要去训练英语模型。银语义模型第二步,训练完引语翼模型之后,我们应该干什么呢?对,应该要得到获得预测评分矩阵,然后进而得到对得到用户的推荐列表,然后最后还有一个副产品,对,那就是我们要利用。
23:20
呃,商品的特征向量,对,当然就是用那个特征矩阵了,对吧,分解出来之后那个矩阵计算对商品的相似度列表啊,这是我们的三步。这些东西都做完之后。最后spark.stop就完成了,对吧?这是我们整体的程序框架,其实我们整体就是这样,就是一开始先做一些预先的定义,然后后边啊,基本的把这个SPA session先创建出来,后边就是数据加载,基本的数据先做一些预处理加载进来,后边就是核心流程,最后spark.stop。
我来说两句