00:00
接下来我们要做的其实就是一步一步把这四个函数实现啊,那首先我们来看一眼,应该在外边实现对吧。第一个第一步,我们要获取当前商品最相似的,呃,不是啊,我们应该是user recently RA,我们首先要获取当前用户最近的case评分,那么大家看一下就是在这个里边。我们传入的参数第一个应该是什么?当时我们给的是那个number是吧?呃,所以这里其实是他的那个number,第二个参数是当前用户的对user ID product,呃,User ID啊,然后最后是一个,所以我们传进来的就是这三个参数,那么它有没有返回值呢?对,当时我们说了,是不是要把它保存成一个数组啊,所以我们的返回值应该是一个。
01:04
对,是一个元组的array,那里边是不是应该对product ID加上一个评分,是不是double啊,Int double类型。呃,然后我们把具体的内容来实现一下。呃,这里面大家会看到就是。我们是不是直接用这个jaice去做操作就可以了,对吧,写下注释啊,从ice中。用户的评分队列里获取评分数据,呃,那这里面我们业务系统在red里边是怎么写这个评分队列的呢?呃,就首先是每个用户都会有一个自己的评分队列,所以说它是一个,呃就相当于是一个一个list对吧?呃,那么他的那个K是一个什么样的形式呢?是一个UID,然后加上。
02:10
User ID这样的一个格式。就是后边这个uz ID是我们实际的那个ID值对吧,前面的这个UID就是字符就是这么写,所以就是它这个队列名字叫什么呢?就是比方说用户1ID是一的用户,它对应的那个评分队列就是UID冒号一。之前大家应该讲过red,我们是不是在red里边很多K都用了这种冒号分割的这种表达式啊,对吧,用这样的形式来去表示它的一个K,方便他后面去做这个筛查,做这个排序,好那么我们这里面就用了这种这种方式啊,这样的一个队列。然后里边的这个value又是什么形式呢。那么这个list。
03:02
List的。键名名称是这样,那么它的value呢,值。格式是,呃,就是同样啊,就是它的格式是一个user,呃,不不是user啊,是一个product ID,对,然后后边一个冒号对应着一个对SC,它是这样的一个格式。然后呢?大家会想到我们如果把它取出来之后,是不是就要用冒号进行分割啊,所以我这里边je如果去做操作的时候,是要对这个list进行一个操作,那这list是怎么操作的,大家还有印象吗?历史的操作L是不是有这样的一个操作啊。
04:02
对吧,就是要去从里边做查询对不对,按照一定的范围去查询一个list,好,那么这里边。大家会看到第一个参数是什么呢?是不是就是它的key名称,我们这里的名称是user ID冒号,然后再加上啊,就是具体的这个user ID对不对,本身user ID是一个string的,呃,本身user ID是一个int,我们这里边把它to string,然后呃把这个字符串合起来就可以了,后边是要跟什么,要跟他的那个range,它的范围对吧?大家看后边是不是要有两个这个范围啊,我们可以给一个零,这是不是从零开始选取,然后选取几个呢?就是传进来的number,这是不是就是我们的个数要选取的那个K对吧,所以这里边把number传进来,呃,大家会看到就是。
05:06
诶,这里边没有问题了,然后拿出来之后,我们还得做一个操作,那就是准备去做一个map操作了,大家看这里边不能直接map,为什么呢。因为呃,这个JA大家知道这是这里边是什么啊,这都是Java代码对不对,所以返回来之后得到的是一个Java的list,那么我们这里边如果直接要在这里去做map操作,是不是还得引入一些别的东西啊,比方说这里边我们去引入scla.collection。里边有一个大家看到Java convers,我们把它引入,诶大家看下面是不是就可以有这个map方法了,就可以对这个Java的里边的一些数据结构进行这个map操作了。好,接下来我们。
06:04
把这个里边的东西拿出来的每一个item怎么样去操作呢?那是不是拿出来的这个item应该就是这样的一个格式啊,一个product ID对应着一个score,所以我们把它做一个切分,还是啊,每一个attribute就应该是。item.split。这里我们切分是用冒号切分,那冒号是不是也得做转业好把它切分出来,然后接下来最后我们想要的是什么东西呢?想要的是不是就是这样的一个元组啊,一个product ID,然后一个SC对吧,一个一个double,所以把attribute的零拿出来。呃,大家会想到本身一个字符串的话,我们先做一个这个对吧,然后to。
07:03
Int转换成product ID。后边ATTRIBUTE1。同样我们做一个chim拿出来之后。应该to,是不是应该to,第二个这个score对吧,这就是我们想要的这个元组的形式,Product ID和score。然后最后得到这个结果,呃,这里边还是这个,就是之前呃Java的这个list。这样的数据结构呢?我们最后是不是要把它。To array转换成。呃,Scla里边的数据结构对吧,然后返回的数据就是这样的一个AR了,这就是我们的这个过程。这个。从。Redis里。
08:03
获取最近numbers评分。这是第一步,然后后边第二步我们实现的是什么?是要获取跟当前的商品最相似的K商品,对吧?所以是get top products,那这里大家注意一下传入的参数,首先第一个是不是还是一个number,当时我们定义的number都放在最前面啊,然后第二个是一个什么东西来着?第二个应该是对,是一个product ID,然后后边是一个user ID。然后最后一个参数是什么?呃,是我们这里边的相似度矩阵,对吧,广广播出来的相似度矩阵,它的value,也就是我们想要的这个相似度矩阵,我这里边就定义成same product。
09:08
对吧?呃,大家这里要注意一下,后边大家看自动匹配上的这个类型是什么呢?是map里边套着一个map对吧,一个int和map,但是这里面大家看到这里会报错,他说tap Miss match,为什么呢。对,因为大家注意啊,就是这里边它默认用到的是scla,就是prefer DeFine里边的这个map类型,而我们这里边前边做了这个转化之后,Collect as map,还有里边的这个图map操作之后,它这里边是什么东西呢?大家看actual里边外层的这个map是skyla collection下面的map。而里边的map是啊,它是一个不可变对吧?Scla collection imutable下边的map啊,所以我们还得根据这个数据类型把它这个做一个转换,那这里边你就不能直接是map了,得用scale下边的collection下边的map,外边这个是map对吧?然后里边这个是collection,呃,以able下边的map啊,所以大家现在你看这个是不是就没有type missmash了啊,这个就没问题了啊,大家看这个如果。
10:31
有点太长的话,我们把它放到下边来吧。好,然后接下来我是不是可以去,呃,大家注意,这里边我应该还用到了跟mango那边的一些连接,为什么呢?是不是我我这里边user ID为什么传进来啊。是不是想把我已经评分过的那些要滤掉啊,不能作为备选先做一个过滤,那这个过滤是不是要从那个评分矩阵,呃,就是我们评分表里边找到对应的用户评分过的那些商品,然后把它做过滤,所以这里边还用到了mongo相关的东西,那是不是把mango的配置要传进来mango?
11:18
呃,那大家想到这里边我直接用mango。Con先传进来,后边可能还会用到mango client对吧,这里边它有返回值吗?我们前面说希望得到的是一个对,就是一个数组,返回一个product product ID构成的一个数组,所以这里我们的返回值就是array。Int。好,呃,那这里边具体要做这个实现。大家会想到,首先我从这个从。
12:00
广播变量相似度矩阵中。拿到,呃,我应该拿到当前商品。的相似度列表。对吧,这个列表是不是就相当于是所有相似的商品啊呃,然后下面去做过滤对不对,第二步是呃过获得用户。已经评分过的商品。然后过滤掉对吧。呃,最后我们把它那个排序输出。就可以了,呃,那么前面这个从相似度里边获取这个,呃,就是这个,呃,当前商品的相似度列表,这个过程可能我们这里边就是从那个map里边直接去取值了,对不对,这里边我定义一个or same product。
13:17
对于这样的一个。变量,呃,这里边呢,我可以直接从传进来的这个新products里边,大家直接去取它对应的那个呃product ID去取值对吧。Same product点,呃,应该去取出对应的product ID的那个列表,因为它已经是map了,我们是不是直接传product ID就可以了,Product ID,呃,最后我们想要的是一个array,所以我把它再做一个to array的操作。拿到这个东西之后,接下来。就要获取已经评分过的列表,那么这里边我们叫做RA exist吧,存在的评分。
14:09
那大家想到这里边,我们怎么去,怎么去找到已经评分过的商品呢?是不是就得用mongo的连接助手了啊,我们就得用mongo客户端,然后去呃,去查询这一部分内容,所以这里边我们先定义一个要操作的这张表吧,我们在data loader里边是不是做过相似的这些操作?我们定义了一个mango client,这里我们不需要去定义了,已经在连接助手里面有了,对吧?呃,那后面是不是要定义操作的这张表啊,我们现在是不是只要需要这个RA这张表就可以了。从RA里面去取东西。呃,这里我们不要用data loader里边的啊,直接用这个自己定义好的就可以,然后这个monggo client。
15:03
呃,这里大家会发现我们这里的monggo client得从连接助手里面去取,是不是?呃,CLA helper.mango client,然后把对应的这个DB传进去,后边是我们的表名,得到的这个是不是就是对这个collection表的操作啊?接下来我们就直接对这个表进行操作就好了,我们要做什么事情呢?里边是不是要啊。是不是要做查询,根据。User ID去查他所评分过的所有商品啊,所以就是一个find,那么find里边给什么参数呢?呃,这里必须给的是一个包装成一个mango DB object,对不对,这里边就相当于是一个一个Jason一样,只不过这里边是一个mango DB object里边就是一个map的形式啊,User ID对应的就是user ID对吧?我们按照这个查询条件去做查询,查询到的东西。
16:15
那大家大家会想到,就是这里边查询到的东西,呃,未必符合我们的要求,是不是它的这个结果大家会看到啊,他其实是就是呃对应这个mongo client base里边定义好的一些东西,我们这里边把它做转换,转换成array。然后我们还需要做map操作。每一个item。呃,大家会想到这里面我们需要什么东西呢?需要什么,不需要什么exist。呃,不,这里边我们还没有去做过滤,过滤是不是要对之前得到的所有的这个相似度列表去做过滤啊,现在我们只是想要拿到,因为这里边查询,查询出来我没有指定说就是投影对吧,没有指定投影到哪几项,这里是不是拿出来所有东西都有啊,就是每一个用户,然后每一个评分,每一个评分值,每个time stamp,我们需要什么东西,对我们是不是只需要那个product ID,所以这里大家注意啊。
17:30
需要。Product ID取出来就可以了,所以这里边我们item大家看这里边是有这个get方法,需要用这个方法去get啊product ID。拿到它,然后它是需要是一个int类型对不对,所以我们需要诶大家看没有to int,只有to string,那我是不是可以先to string,然后再to啊,把它转换过来就可以了,好,那接下来就是做过滤了啊从呃,就是所有的相似。
18:15
商品中进行过滤,所以这里边我们用到的是all products,然后要去做一个。呃,里边我们给一个什么样的条件呢?大家想一想。对,如果说在这个RA exist,呃,一个exist里边的话,就是我们每一项对吧,这里边的每一项如果在这个RA exist这个列表里边的话,是不是它就应该给过滤掉啊,我们应该取的是不在这个里边的,对不对?呃,那大家会想到这里边我们应该给一个什么样的表达式呢?是不是应该是不在。
19:02
就是是不是有。如果它里边不包括我们当前的这个X对应的那个product ID的话,那么就呃就就把它滤出来对吧?呃,那这里边注意啊,X是什么呢。X是前边我们取出来的那个相似度列表,相似度列表是不是里边有两个元素啊?相似度列表是不是里面本身是一个一个product ID对应的一个相似度那个score啊,所以这里我们要用的是什么。是不是X的一啊,这是它的product ID,所以就是说它的product ID如果不在exist里边的话,诶,这是符合我们要求的,把它滤出来好,那对应的大家就会想到我后边是不是还应该可以对它做一个排序,这个排序是不是就要用第二个元素,也就是相似度的那个大小来做排序了,所以我们可以写一个south把它做排序,那当然了,后边可以take take是不是就是选取前number,根据这个来来做一个截取,最后最后我们要的是这里边还是一个二元组,对吧?我们最后是不是只要他的ID就够了。
20:24
我们希望得到的是不是只是一个int类型的RA啊,所以再做一个转换map一下,是不是只要拿他的product ID就够了,诶,所以把这个转换出来返回就可以了。所以这一步我们其实就是。就是进行了什么呢?啊,就是获取当前商品的相似列表,并。
21:10
过滤掉。用户已经评分过的。作为备选列表,对吧,这是我们的这样一个处理的过程。
我来说两句