从2016年google的wide&deep和youtube dnn两篇标志性的paper开始,深度学习在推荐系统中的应用已经遍地开花,个人觉得可以简单粗暴地将其归纳为两大阶段,第一阶段是dnn在推荐系统中的可行性验证并规模化应用,如wide&deep/deepfm/deepcross等的大规模落地;第二阶段是各大公司在dnn的基础上,结合自家的业务特点,做模型二次创新,如阿里结合综合电商场景门类大而全的特点,研发了DIN系列模型。
我们来聊聊第一阶段,dnn在推荐系统落地的核心操作之一。
先来看看基础的dnn,我们知道,dnn一个相对黑盒的算法,所谓黑盒,指的是可解释性差,比如他给出你一个预测结果,你无法根据模型结构参数精确解释模型为什么会给出你这个结果;而并不是你丢给它一堆数据,它会自动地帮你预测个结果出来。是的,我们需要把我们业务场景的数据特点抽象出来,并把它告诉模型,即将抽象出来的数据共性表达在模型当中。当然了,这也可以通过大量且细致的特征工程来实现,但这种方式不具备复用性,在这里不展开讨论。
我们先来看看,如何把数据特点抽象到模型结构里吧,先来看看典型的文本和图像领域是怎么做的。
文本数据是典型的强序列化数据,所谓强序列化指的是数据单位的顺序关系蕴含着重要的信息,比如“人吃鱼”和“鱼吃人”,同样的三个字,不同的顺序表达的意义完全不同。那么如何捕捉这种序列关系呢?词典+ngram看起来是种可行的方法,但它带来的维度爆炸让人无法接受。rnn系列序列化模型优雅地解决了这个问题,即把数据的序列化关系表达在了模型里面,又没有引入过多参数。
而图像本质上是一个稠密矩阵,数据携带的信息密度较大,不同的图片之间,既有基础的底层共性,比如边缘/明暗;又有中层的略带有一定差异共性,比如图像里不同人的人脸,既有共性(都是人脸),又有差异(不同人的人脸),还有更上层的差异,如不同的label。图像多层级信息共性与差异特点明显,动辄几十上百的多层网络结构被设计出来表达图像数据这一特点,多层网络结构也引入一些问题,比如梯度消失/爆炸、参数规模大等,残差网络与更适配的**函数的应用,很好地解决了梯度传播问题。另外,图像局部相关性特点明显,cnn的卷积核划窗和pooling操作捕捉了这一信息,且降低了模型参数量。
再来看看推荐场景,一个业务中通常有大量待推荐的item,而获得较多曝光机会的item往往只是头部少数,如果再做一下特征交叉,百亿甚至千亿的特征空间维度也不稀奇,这就是推荐场景的显著特点:特征大规模稀疏。面对如此庞大的特征规模,直接将样本喂给dnn模型显然是不可行的。我们来看看google的工程师们是怎么解这个问题的。
如上图,先把离散特征按照语义分组,比如item一级类别是一组,二级类别是一组,用户的省份是一组,总之将离散特征氛围若干组。接下来,每一组离散特征单独初始化一个embedding矩阵,矩阵embbeding维度通常是O(10),这里就以32为例。训练模型前向传播时,每个组的离散特征查找到其**的隐向量(若是多值特征,可做pooling操作),然后cancate成一条向量,相当于把每个组的特征语义都展开放到一起,接着喂给下一个全联接层。这种方式即充分保留了原始特征的语音信息,又大大较少了参数量。当然了以上每个组的embedding矩阵维度,并不一定要设置成一样的,可根据特征本身的信息容量和数据量个性化配置。
以上,是深度学习在推荐系统应用的核心操作之一。
个人非nlp/cv专业人士,相关部分均为个人理解,如有错误,还请指正。
微信公众号:world2vec
欢迎关注