00:00
前面我们已经完成了前两步,就是从red里边拿到了最近的呃,Numbers评分,然后后边又获取到了当前相商品的相似列表,然后把它作为了一个备选列表,那接下来我们还有第三步,其实就是结合前面已经得到的这些数据,最后是不是要。计算每一个备选商品的推荐分数啊啊,所以这里边我们要做的是compute实现这个实现这个函数,呃,这里面是。计算每个备选。备选商品的。推荐得分。好啊,那这里边大家还是看一下第一个传进来的这个a int,这是个什么东西呢?这就是我们刚才第二步算出来的备选列表对吧?呃,所以这里边我们就根据上面的这个定义好了,叫做candidate product,对吧?
01:11
然后第二个,呃,这个原组的一个列表,这是我们从red里边选取出来的最近的K评分啊,我们把这个也复制过来。最后啊,这个看起来比较复杂的这些东西,这是。啊,我们要传进来相似度矩阵,因为还要选取,对于每一个备选商品,是不是还要看他跟已经评分过商品的相似度,还要再去根据相似度去做加权计算啊,所以这里边我们还得把相似度矩阵传进来,那么我这里边就直接抄了啊,把这一部分整个复制下来。好,呃,然后接下来大家想一想,在这个过程当中,它的返回值应该是什么呢?有没有返回值?返回值肯定是有的,你要计算每个备选商品的推荐得分了,而且前面我们其实已经想的很清楚了,最后是要得到一个当前用户的实时推荐列表的啊,所以这里我们要做的事情还是比较多的啊,就是不光要对每一个做一个计算,最后还要提取成一个列表的形式,那最后是什么样的形式呢?就是一个product ID和score构成的一个数组就可以了。
02:29
那所以我们当然返回值就应该是一个。里边product ID应该是一个int,那对应的score就应该是一个double,对吧?好,这就是我们要做的这些操作,大家如果看着这个也是有点远的话,我们把它放在后边。好,接下来我们来做一下实现啊,那首先第一步我们应该是做什么呢?我们先定义出来。
03:09
因为大家根据我们之前的这个公式,接下来我们是要按照公式来算了,对不对,这个公式里边是不是有三项啊,而这三项计算的过程当中又各有不同,第一项这个基础项是要做一个求和,要做加法。然后第二项第三项是不是要做一个计数的统计啊,所以相当于是有一个计数器,那我们在这里边怎么样去做处理呢?因为这里边我们传进来的是所有的备选商品和所有的这个呃,之前已经评分过的K次评分,所以我们这里边要保存他们每一个待选商品和和每一个这个已经评分过商品之后算出来这个按照权重算出来的推荐得分,我们最后把它保存在一个,保存在一个可变长度的数组里边,就每次统计一个,然后把它追加上去,每统计一个追加上去,这样是不是就可以完成我们的这个保存,最后做统计的时候,对这个数组再做一个操作就可以了,这是我们的基一个基本想法,好定义。
04:19
一个。呃,当然这个长度可变数组的话。应该是一个什么,是不是就应该是一个array buffer啊对吧?呃,应该是一个瑞buffer,然后我们用它来保存。每一个备选商品的基础得分,呃,所以大家会想到这一个a buffer,我们就直接在这里先定义出来吧,一开始我们先定义一个空的应该就可以,对吧?啊,这里这里我们就叫scores吧,那么这里边我们用要用到的buffer呢?应该是在scale下边的collection。
05:11
下边有一个muable,里边会有a buffer,对不对,我们把这个定义出来。它里边的结构。应该是一个product ID,然后还有一个对,还有一个得分对吧,所以是这样的一个结构啊,Product ID,然后score,所以这就是我们最经典的这种模式,就是一个ID一个一个score,那当然这里就应该是一个int,后面是一个double,对啊,那么我们先初始化一个这样的一个空的数组,后面要加上括号对吧。然后后边我们还要定义这个就是后面的两项,前面这是基础得分,后边还有一个增增强项,奖励项,或者叫增强因子,然后还有一个惩罚因子,对吧,减弱因子,所以我们这里边呢,在定义,那那这个东西大家想我用什么来保存呢?
06:14
当然我们也可以用一个这个可长度可变的数组来保存更简单的方式,大家会想到这里边它其实就是一个计数器,对吧,那我其实是不是可以哦,直接用一个变量把它表示就完了嘛,表表示出来之后,我遇到符合条件的,比方说评分大于三的,哎,这个计数器加一,如果要是小于三的,诶,减一,呃,不,不是减一,就是我们另外一个计数器应该加一对不对,哎,所以是这样的一个想法,那这里边对于每一个商品都应该有对应的这样的两个计数器。那所以我们所有商品都要定义的话,那是不是保存成一个map会比较方便啊。一个K,一个value k就是这个商品的ID,那对应的那个value是不是就是它的计数器的那个值啊,所以我们这里面其实就可以定义两个map用于。
07:13
对,保存每个商品的,呃,就是高分和低分的计数计数器,对吧,用用作用作这样的一个计数器,所以这里边我们就去定义一个,比方说高分的这个我叫增强因子,叫increase map吧。呃,他应该用,当然了,大家想到也是skyla collection下边的muable里边的啊,我们用一个哈希麦,这样就可以随时往里面增加对不对,随时往里面增加我们对应的这一个key value,好,那么这样的一个哈希map它。
08:01
当然需要去指定它的这个类型啊,呃,那是本身这样的一个计数器,是不是应该是一个product ID,然后对应着一个什么啊。对,对应的一个什么?对应的一个就是一个一个计数对不对,一个count对吧?所以我们这里边就用一个int和int这样的类型,是不是就可以了,1MAP就够了,Map,呃,大家大家觉得是只要定义一个map就够了是吗?对呀,后面一个呃,后面一个那用什么呢?组哦,对,大家可以想到就是后面这个用元组也是可以的,对吧?这这个当然是没问题,对,那那我们这里就用这个元组干脆来实现一下吧,我们把它定义成这个inre count和decre count,对吧。
09:01
用这种方式来实现一下,呃,那我们就定义定义一个map对吧?呃,这里边大家就可以认为这个叫呃,叫偏移量,就叫shift map吧,所以这里边我们给出来的后面就应该是一个二元组对吧?啊,那么后面大家加上括号,把这个先给一个初始化定义出来,那后边我们拿到的这个东西呢,就应该是它里边的这个inre,呃,这里面大家还会有一个问题,大家觉得有什么问题吗?如果这么写的话,有一个问题。就是呃呃以以多少分,我们这个随便定这个,你就比方说我们三分作为一个分界,主要是在后边我们更改它的时候。大家会想到你就是更改它的时候,可能就没那么方便,我应该把它先选,就是把它先拿到对吧,拿到之后是不是得看后边有没有值啊,那你说假如说我是count有值d count没值这种情况,当时我存储的应该是一个什么状态呢?那我还得一开始是不是把所有的做一个初始化啊,是不是这样啊,所以就有这个问题可能会稍微麻烦一点,那如果我们要是定义两个map的话,像刚才我们这样啊,定义两个map。
10:30
好处就在哪里呢?哎,是不是一开始我就不需要初始化,你只要来了一个属于,哎,就是它这个这里count要要要加的话,我直接往这里边去去加进去就可以了,如果没有的话,把它添加进去,如果有的话直接加一是不是就完事了呀,就不涉及到后边这个元组的判断和操作了,呃,就是大家可以用这个元组形式尝试去做啊,我们这里边就还是用稍微简单一些的方式吧,呃,这个大家应该能想到吧,好,那除了这个inre map之外,我们还应该有一个对decre map,这其实就是一个考察它的增强因子,另外一个考察它的减弱因子,它们的定义都是完全一样的,但是大家看起来好像有点重复啊,就是大家可以定义一个元组,去把它做一个整合好,已经有了这两部分东西之后,接下来我们是不是就应该去对每一个。
11:30
备选商品计算评分了,所以接下来要放循环对吧,便利。每一个备选商品,呃,然后我们应该要去把计算和以评分商品的相似度好,那这里我们会用一个for循环去做这件事情,大家会想到就除了首先我应该去拿到所有的,呃,这个candidate,对吧,我们应该有candidate candidate。
12:21
Product。它从哪里去取呢?就应该从我们传进来的candidate products里面去取,呃,所以这样的一个表达式大家应该记得吧,呃,在这个SKY里边可以这样去写一个for循环,另外除了它之外,我们对于每一个备选商品,是不是相当于也得对每一个已评分的商品,他们都得去算一个相似度,然后挨个去计算啊,因为那个对于每一个备选商品,这个求和是不是跑不了啊,求和的过程就又是一个便利的过程,所以它其实一个双重的for循环,那在skyla里边大家知道可以把它写到一起,呃,这里边我们再去定义一个,呃,呃,就是我们那个叫什么user recently,对吧?我们从user recently ratings里边便利每一个最近的评分,呃,然后把它做一个这样的操作。
13:20
好,那接下来我们就看这个for循环里边到底该怎么做呢?首先第一步是不是应该从相似度矩阵里边。拿到,呃,获取。就是当前备选商品和对,和当前的这个考察的这个以评分商品之间的相似度,对吧?和当前以评分商品间的相似度,呃,这里面可能稍微有一点麻烦,就尽管说我们前面已经把它都存到一个map里面了,大家想那这其实非常简单嘛,我直接这个map里边,首先根据第一个这个candidate他的那个ID取出来,后边再根据对那个呃,User recent RA里边的那个ID再取一次不就完了吗?呃,但是这里大家注意一下,我们规范化的话,从mapb里边取值的时候,你得注意,万一它那个列表里面没有怎么办呢?有没有这种可能啊,对,是有可能的,因为当时我们存那个相似度列表的时候,其实是有筛选条件的。
14:39
对吧,大于这个零点几以上的才把它筛出来,所以这里边我们可能还得去做更多的判断,就是说假如没有的话,那是是不是应该得给零啊,啊,得有这样的一些,就是异常的一些考考虑,所以这里我们还是定义一个定义一个函数吧,呃,Get all else是吧?对,如果要是获取不到的话,就直接给else也是可以的。呃,或者我这里边给大家写一个函数,大家看到包装起来啊,放到后面再去实现product,呃,我们叫product seem score,就是它的相似度对不对,拿到两个商品之间的相似度,那这里边我们要传的其实是candidate product,还有一个是user RA,要拿到他的那个product ID对不对?
15:39
这是不是就已经是product ID了,那user recently RA这本身是什么呢?对,它是一个元组,这个大家一定要注意啊,它是product ID后面还跟着RA那个score的那个元组,所以我们得取出它的是不是第一个元素啊,对,所以说是取它的下划线一啊,当然了,如果说我们要把它再包一层的话,那就确实得麻烦一点,那是不是还得把这个相似矩阵再传传递一遍啊啊,这个就是确实麻烦了一点啊,好,我们把这个相似度矩阵再传下去,最后就可以得到这样的一个相似度的评分。
16:19
接下来我们就可以把它呃做处理了,那这里边我们可以比方说我还是有一个判断啊,只取呃,比方说我这里面只取same score,对大于某个数的啊,比方说我这里还是0.4啊,这就相当于又有筛选条件对不对,按照我们某个条件去做筛选,然后接下来哎,我们就可以按照公示进行。加权计算,呃,那这里边大家会想到我这里边最,呃,因为这里面涉及到的是每一个。
17:09
已经评分的商品对吧?呃,所以这里面我还不能做叠加呢,应该是到外边去才能做叠加,或者是我如果想做叠加的话,是不是得定义一个一个sum,类似于sum一样的东西啊。呃,这里边我不定义sum,而是用另外一种方式,我之前不是已经定义了一个长度可变的数组scores吗?我可以把每一个对算出来的那个基础得分是不是往这里边去填啊,填进去之后,最后我是不是可以对这个score按照它的product ID求后边这个平均数就可以了啊,就是相当于后边我可以去group by对吧?然后聚合起来之后把后面做一个求取平均数或者求和就可以了。所以如果按照这样的一个思想的话,我直接可以scores加等于后边加等于什么呢?对,我是不是应该把product product。
18:09
嗯。呃呃,应该是candidate对吧?对,Candidate product这个这是ID对吧,这是product ID先放进去,然后后边我还要一个他的那个得分,得分应该怎么算?对,应该是same score。是不是要乘以加权对吧,当时我们的这个公式是要乘以它的评分,评分是什么来着,是不是还是在user recently RA里边啊,它是个二元组下划线,一是ID是不是二是评分啊对,所以大家注意啊,我们这里把这个二拿出来做一个计算就可以了,这里大家稍微要注意一下,这里因为我们用到了这个就是瑞buffer,它的这个加等于,那大家会想到这其实它是做了一个。
19:03
呃,大家看到这是这是做了一个呃运算符重在的对吧,相当于它是一个函数对不对,所以如果我们这里直接这么写,写的话,肯定是有问题的,为什么呢。因为我们其实想要传进去的是不是应该是这样的一个元组啊。但是事实上,如果我们直接这么去写,是不是这里默认会把这个括号当成是我们的函数后边调用的时候的那个括号啊,所以这里大家稍微注意一下,对,我是不是还里边应该把这个圆组再扩一层啊,对吧,还应该再把它括起来,这里大家稍微注意好接下来,呃,当然这里面还报错,那是因为我们前面这个函数没实现对不对,我们先把这个先写完,呃,那后边有了这个基础评分项加加权计算。获得获呃得到基础评分,然后接下来我们是不是还应该有,呃,是不是要判断它那个到底是高分还是低分对不对,呃,所以接下来我们去if判断一下。
20:12
它的分数是是不是user recently RA里边的第二个元素啊,对我们的规则,比方说就是大于三吧,按照大于三来考虑,如果大于三的话,那是不是对当前的增强因子re map里边就得对应的这个product ID,对应的那个计数器就得加一对不对?呃,所以当前的product ID是什么呢?是对,是candidate product,这是它的那个ID,好,那后边我就让它等于,呃,这里边大家会想到我直接加一加等于一不就完了吗?呃,大家要注意它有可能没数对不对?因为一开始我们是空的,所以呃,这里边就可以去candidate,是不是可以get all else啊对吧?呃,这里边我们不能直接取得,直接get or else。
21:09
呃,或者我们可以直接get头default,为什么呢?呃,对,就是default是不是应该给零啊,就是如果要没有的话,默认就是零,所以这里边candidate product,然后给零,如果有的话就加一,没有的话是不是默认就是零啊,好,这样就可以了。呃,那么else的话是不是就相当于是decre map要去加一啊呃,对应的这个位置加一,所以这里我就直接抄下来了,当然这里边我们应该用re map get default对吧,取出来,然后如果没有的话是零加一。好,这一部分我们都已经做完之后大家看啊。呃,这个else结束到这里是我们整个的这个就是当前的备选商品和当前的已评分商品啊,这个就全部判断完完成了,把这个对应的项就都已经算完了,然后到这里。
22:10
是for循环结束,For循环结束之后,大家会想到是不是这个score scores里边就是一堆这个元组的一个列表啊,然后接下来我们可以根据它的product ID是不是做聚合啊,然后去求它的那个平均数就可以了。
我来说两句