相似商品推荐算法-机器学习
1. 问题背景
设想如下的场景:
- 当用户浏览某个商品的时候,我们需要向其推荐相似的商品以增加用户购买的概率
- 当有新商品上架的时候,需要向用户推销,如何找到可能对该商品感兴趣的推销对象
- 当某一个品牌、厂家或者BBC中的小B进行促销活动时,如何推销给感兴趣的用户
再来看京东APP的相似商品页面:
搜索平台如何协助业务实现这样的需求。
2. 问题分析
假设存在这样的前提:
用户如果对某个商品A感兴趣(可能包含点击、浏览、收藏、加星、购买等行为),那么用户也有很大的概率对和商品A相似的商品感兴趣。
上述的商品推荐、广告营销等问题就可以转化为寻找相似商品的问题。
3. 解决方案
商品相似算法有很多:基于商品的协同过滤、强关联规则等等。不过这些都不在我们考虑的范围(正在开发的推荐平台会实现这些算法),我们选择一种最方便、最符合我们应用场景的算法:基于商品内容的相似度算法。 基于商品内容的相似度算法只依赖于商品的元数据,不依赖于外部数据,简单方便,没有系统冷启动的问题。
3.1. 余弦相似性
余弦相似性是指通过测量两个向量内积空间的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。两个向量有相同的指向时,余弦相似度的值为1;两个向量夹角为90°时,余弦相似度的值为0;两个向量指向完全相反的方向时,余弦相似度的值为-1。在比较过程中,向量的规模大小不予考虑,仅仅考虑到向量的指向方向。余弦相似度通常用于两个向量的夹角小于90°之内,因此余弦相似度的值为0到1之间。
以二维空间为例,如上图所示,a,b是两个向量,我们要计算它的夹角θ,余弦定理表明可以用以下公式求得:
假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:
已经证明余弦定理对n维向量也成立。一般的,A,B是两个n维向量,A是 [A1, A2, ..., An] ,B是 [B1, B2, ..., Bn] ,则A与B的夹角θ的余弦等于:
基于上述理论,我们得出商品内容相似度算法为:
- 根据模型,从商品元数据中提取出商品特性
- 将这些特性组合成商品的多维向量
- 计算两个向量的余弦相似度,值越大表示商品越相似
3.2. 商品特征向量提取
哪些商品的属性作为特征向量,搜索平台是在配置文件中配置的。目前采用brand(品牌)、salePrice(销售价)、salePoint(卖点)、tags(标签)、props(扩展属性)、spuId(标识SPU)、title(商品标题)、cats(商品类目)。这些属性处理方式是不同的,主要分为以下几种:
3.2.1 不分词的字符串字段
对于不分词的字段,比如brand、spuId,直接比较是否相等即可。
比如计算商品A{brand:"华为", spuId: 1000}和商品B{brand:"华为", spuId: 1001}、商品C{brand:"苹果", spuId: 1002}的相似度。商品A的[brand, spuId]向量为[1, 1],对于商品B,应该brand和商品A相同,spuId和商品A不同,则商品B的对应向量为[1, 0];商品C brand和spuId和商品A都不同,则商品C的对应的向量为[0, 0]
3.2.2 不分词的数组字段
对于不分词的数组字段,比如salePoint、tags、cats,可以采用如下的公式计算向量值。以tags字段为例,求商品A和B的tags字段的向量维度值。
按照上面的公式,商品A{tags: ["华为", "千元机", "618大促"]},商品B{tags: ["苹果6S", "玫瑰金","618大促","电信4G"]}。 商品A的tags字段向量维度值为1, 商品B的tags字段向量维度值为 1/6=0.167。
3.2.3 数值字段
对于价格来说,如何衡量商品的价格向量维度值比较困难。比如商品A的价格为100, 商品B的价格为50,商品C的价格为120,如何计算商品B和C的相对于商品A的价格维度值。我们可以获取所有商品的价格区间,获取最大值和最小值,然后使用商品和商品A的价格差的绝对值除以区间值,公式为:
以上面的例子来说,商品的价格区间为[50, 120],价格区间段大小为70,那么商品B的价格字段向量维度值为:1 - (|50-100|)/70 = 1 - 0.714 = 0.286;商品B的价格字段向量维度值为:1 - (120-100)/70 = 1- 0.286 = 0.714
3.2.4 分词的字符串字段
假设商品A的标题为“Apple iPhone 6s (A1700) 64G 玫瑰金色 移动联通电信4G手机”,商品B的标题为“【电信赠费版】Apple iPhone 6s Plus 64G 玫瑰金 移动联通电信4G手机”,如何计算这两个字符串的相似度呢?
基本思路是:如果这两句话的用词越相似,它们的内容就应该越相似。因此,可以从词频入手,计算它们的相似程度。下面是具体的实施步骤:
分词
使用千米自定义分词器对标题进行分词:
商品A标题:Apple / iPhone / 6s / A1700 / 64G / 玫 / 瑰 / 金 / 色 / 移 / 动 / 联 / 通 / 电 / 信 / 4G / 手 / 机
商品B标题:电 / 信 / 赠 / 费 / 版 / Apple / iPhone / 6s / Plus / 64G / 玫 / 瑰 / 金 / 移 / 动 / 联 / 通 / 电 / 信 / 4G / 手 / 机列出所有的词:
Apple iPhone 6s A1700 64G 玫 瑰 金 色 移 动 联 通 电 信 4G 手 机 赠 费 版计算词频
商品A标题:Apple 1, iPhone 1, 6s 1, A1700 1,64G 1,玫 1,瑰 1,金 1,色 1,移 1,动 1,联 1,通 1,电 1,信 1,4G 1,手 1,机 1,赠 0,费 0, 版 0
商品B标题:Apple 1, iPhone 1, 6s 1, A1700 0,64G 1,玫 1,瑰 1,金 1,色 1,移 1,动 1,联 1,通 1,电 2,信 2,4G 1,手 1,机 1,赠 1,费 1, 版 1构造标题词频向量
标题A:[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0]
标题B:[1,1,1,0,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1]计算两个标题词频向量的余弦相似度
商品A的标题字段向量纬度为1
商品B的标题字段相对向量维度为:(3+9+2+2+3)/ 21.63 = 0.878
可以看到这商品A和B标题的相似度是比较高的。
3.3. 计算两个商品的余弦相似度
假设商品的向量维度指标依次为[brand(品牌), salePrice(销售价), salePoint(卖点), tags(标签), props(扩展属性), spuId(标识SPU), title(商品标题), cats(商品类目)]。 则商品A的特征向量为[1, 1, 1, 1, 1, 1, 1, 1],假设商品B的特征向量为[1, 0.7, 0.5, 0.6, 0.7, 0, 0.8, 0.3]。
根据余弦相似度公式,商品A和B的相似度为:4.6 / (2.8284 * 1.8221) = 0.8926
3.4. 基于权重的余弦相似度
在前文中提到的算法,特征维度没有考虑特征的权重,所有特征的权重都是相同的。对于购买商品来说,价格、品牌、价格和标题等特征权重设置为相同可能不合理,所以需要对用户的购买行为进行分析,分析主要特征,形成权重特征向量:
特征加权之后相似度计算公式如下: