上一篇讲了聚类算法中常用的一个k均值算法,接下来举一个用到实际中的例子。

我们的数据中有一项是希望用户选择几个自己喜欢的游戏,然后我们根据他的喜好,推荐跟他类似喜好的玩家。比如我们给定几个游戏或游戏类型,(A, B, C, D, E, F, G),然后用户甲选择时,选择了自己喜欢A, D, E, G,然后用户乙选择了B, D,E,用户丙选择了B, C, D, G ,等等等等,假设我们已经有了100个用户的喜好数据,然后当一个新用户进来并从中选择完自己喜欢的游戏类型后,如何迅速推荐给他和他相似游戏爱好的人,并告诉他相同游戏爱好的一个交集信息?

感觉这个数据模型用作聚类相当典型。我们把(A, B, C, D, E, F, G)当作一个数据,我们用一个二元数据(0,1)向量来表示一个用户喜欢哪些游戏,比如用户甲喜欢A,D,E,G,用0来表示没选择,用1来表示选择,这样我们得到用户甲的向量是(1, 0, 0, 1, 1, 0, 1),同样用户乙的向量是(0, 1, 0, 1, 1, 0, 0),用户丙是(0, 1, 1, 1, 0, 0, 1) 等等,这样我们就产生了这100个用户的游戏喜好向量。

然后我们就用上一篇提到的k均值,将这些进行聚类,相似的向量被聚在一起。在k均值中用的计算距离的函数是余弦相似度,余弦相似度可以忽略每一维中是0的,这个很重要。目前我们是有7个游戏,假设我们有50个游戏,而用户选择的必然是很少一部分,这样产生的向量中只有很少一部分是1,然后我们刚好关心的就是1的部分,而不关心是0的部分。用余弦相似度计算两个向量的相似度时,如果该维有一项是0,在计算时就会由于乘法操作变为0,从而忽略该项。所以这里用余弦计算相似度刚好满足我们的需求。

在k均值的计算中,我们假设把k设置成5,这样出来的聚簇就有5簇,我们假设结果比较好,也就是各簇之间的向量相似度比较小,而簇内的各向量的相似度比较大。当得到这5个簇后,我们也就得到了5个质心,这个质心可以理解成每个簇的“核心点”,如果在k均值的计算中,每步我们都使用平均值来重新计算质心,那么一个质心的数据可能是这样(0, 0.5, 0, 0.666, 0.3, 0.5, 0.6),这样我们就有5个这样的质心点。然后我们这个质心点的信息存入数据库(需要存储的就是它的质心向量是什么,它代表了哪个簇),同时把每个簇下都有哪些用户也存入数据库。

以上这些操作都是我们先在后台生成好的,存入数据库,因此上面这些操作多耗些时间没问题,只要根据新的用户数据,定时更新簇和质心信息就可以了。也就是说上面的这几步都没有实时产生的要求。

当一个新用户进来填完自己的游戏选择时,我们就要立刻推荐给它相似的用户了,这一步要求是实时的。很简单,我们得到这个新用户的游戏向量,例如Ta喜欢B, D, F, G,那么向量就是(0, 1, 0, 1, 0 , 1, 1),然后我们计算这个向量和5个质心向量的距离(同样使用余弦相似度函数),找到一个最相似的质心向量,这样就找到了这个质心所代表的簇,然后从这个簇里找用户就可以啦(如果是推荐的话,可以简单的随机挑选用户出来)。这样挑出来的用户和新用户的向量是相似的,那么下一步要找到一个交集信息打印出来,只要找这两个用户同时为1的维就可以了。

目前大概是想这么做,初步试了下,似乎效果还不错。😄