平时大家是如何做推荐系统的Embedding的呢?是不是这样:
代码语言:javascript复制layers.Embedding(vocab_size, dim_size, dtype='float32')
如果是很高维度的类别特征呢?比如电商场景下的itemid,可以有上亿,然后可能会这样:
代码语言:javascript复制hash_itemid = hash(itemid, vocab_size)
layers.Embedding(vocab_size, dim_size, dtype='float32')(hash_itemid)
就这样吗?效果好吗?不知道,反正跑起来了,看着AUC也不错。
《Learning to Embed Categorical Features without Embeeding Tables for Recommendation》这篇论文告诉我们,别再瞎操作了,用Deep Hash Embedding(DHE)就对了,AUC也有保障。
看下之前embedding和DHE的大致对比:
对比下左右两边很容易看出两者Embedding的区别,左边就是传统的embedding,先one-hot再lookup,这里vocab有2百万,32维度,对于一个ID会映射成32维.右边就是用DHE的方式,先通过Identifier Vector映射成1024维度的向量,这个向量并不会接受梯度,然后这个向量会通过多个mlp映射成32维度.你能相信DHE只用了传统方式1/4的参数却达到了相同的AUC吗.
为什么要用DHE
其实在背景中已经说了一部分理由了,主要总结为以下3点:
- 字典大小过大:推荐系统中像是videoid,itemid,advertiserid都很大,不像NLP的bert,字典只有30K(因为bert用了word-piece),我们无法用NLP的方法对推荐领域的ID特征进行降维,也没办法直接Lookup一张巨大的词表.
- 动态输入:这里可能很多炼丹师没有切身体会,十方作为广告领域的炼丹师深有体会,bert可以一直用一张词表,因为word-piece后的word segment基本不会变化.但是像广告,广告主每天都在创建广告,id每天都在更新,与此同时很多广告id也被废弃(广告主停投).
- 数据分布不均:类别特征也总是分布不均的,长尾的特征对embedding极其不友好.
总结下来用DHE就对了.
Deep Hash Embedding
先看下什么是好的encoding?
唯一性(U):好的encoding对每一个不同的特征编码都要是唯一的.如果这个保证不了,后续的decoding就没办法区分不同的特征了,那模型效果也大打折扣.
相似性(E-S):有唯一性并不足够,相似特征编码后也要足够相似.比如二进制编码,8(1000)和9(1001)就比8(1000)和7(0111)看着相似,这就会给模型带来困扰,误导后面的decoding过程.
高维性(H-D):这个很容易理解,越高维区分度越高,极端情况就是one-hot了,区分度最强.
高熵性(H-D):众所周知,熵越高信息量越高,我们肯定不希望有哪一位编码是冗余的.
了解了什么是好的encoding,我们看看哪些encoding满足这些条件:
好吧,说来说去只有DHE满足了好的encoding的所有条件
,所以DHE是如何编码的呢?
DHE先用k个全域哈希函数,把id映射成k维,每一维度都是1~m,这时候相当于把id映射成了k维度的INT,但是这样是不能够喂给Decoding(DNN)的,这里有两个方案:
1、Uniform Distribution:因为每一维都可以看作1~m均匀分布,所以直接把这k维度INT normalize了.
2、Gaussian Distribution:先用第一种方式,再用Box-Muller处理,把均匀分布转变为正太分布.
论文说实践证明两种效果都很好,所以大家用第一种,简单快捷.这里需要注意,k需要很大效果才好,论文里的k用了1024.
至于decoding(就是个DNN)就不过多介绍了,这里用了h层网络.需要注意的是,论文提到这种encoding-decoding方式很容易造成欠拟合,论文中的解决方案是把激活函数从ReLU换成了MISH(如下图),同时这里DNN增加dropout,正则化也不会有什么增益.
实验效果也不赘述了,可以参考原文,在AUC各项指标中,DHE都优于各种hash方法.
参考文献
1、Learning to Embed Categorical Features without Embeeding Tables for Recommendation
https://arxiv.org/pdf/2010.10784.pdf