王喆《深度学习推荐系统》
文章出处:https://blog.csdn.net/wuzhongqiang/article
1. 前言
今天是推荐系统传统模型的第四篇,也是传统推荐模型的最后一篇, 迎来的是因子分解机(Factorization Machine, FM)和域感知因子分解机(Field-aware Factorization Machine, FFM), 这两个属于因子分解机模型族, 在传统逻辑回归的基础上, 加入了二阶部分, 使得模型具备了特征组合的能力, 在上一篇文章里面谈到了逻辑回归, 这是一个简单、直观、应用的模型, 但是局限性就是表达能力不强, 无法进行特征交叉和特征筛选等, 因此为了解决这个问题, 推荐模型朝着复杂化发展, GBDT+LR的组合模型就是复杂化之一, 通过GBDT的自动筛选特征加上LR天然的处理稀疏特征的能力, 两者一结合初步实现了推荐系统特征工程化的开端。 其实, 对于改造逻辑回归模型, 使其具备交叉能力的探索还有一条线路, 就是今天这篇文章要介绍的POLY2->FM->FFM, 这条线路在探索特征之间的两两交叉, 从开始的二阶多项式, 到FM, 再到FFM, 不断演化和提升。
所以今天这篇文章的脉络会很清晰, 首先会先从POLY2开始,简单介绍一下POLY2模型的原理以及存在的不足, 从而引出后面的FM模型, 这个模型是2010年提出来的, 在POLY2的基础上把二阶交叉特征前面的权重换成了各自特征隐向量的内积形式, 这个模型还是比较重要的, 虽然现在不怎么用了, 但是他里面的隐向量思想的身影在深度学习的embedding里面得到了继承和发展, 所以接下来就会介绍FM模型的原理和一些公式的推导, 这个模型依然有点不足, 所以最后会介绍FFM模型的原理, 这个模型基于FM模型对权重又进行了改进, 引入了域的概念, 使得交叉特征的信息表达更近一步, 对了, 这个模型是2016年提出来的, 比GBDT+LR模型还晚了一些。这个模型感觉思路也是非常的有意思, 所以也是挺重要的, 为了更好的理解FM和FFM, 每一块的后面也会加上代码实践部分, 亲自玩一下这些模型 😉
大纲如下:
- FM? 我们先从POLY2开始
- FM模型的原理及代码实战
- FFM模型的原理及代码实战
Ok, let’s go!
2. FM? 我们先从POLY2开始
在前一篇文章中已经说过, 逻辑回归模型已经把TOPN推荐的问题转成了CTR预估的问题, 也就是将特征做一个线性组合, 然后通过sigmoid得到一个概率值, 这个概率值表示用户点击某个商品的概率, 逻辑回归模型相对于传统的协同过滤来讲, 已经可以把用户特征, 商品特征以及上下文特征进行了利用, 但是逻辑回归存在很大的一个问题就是只对单一特征做简单加权, 不具备特征交叉生成组合特征的能力, 因此表达能力受到了限制, 还记得逻辑回归中y的公式吗?
这里就可以看到, 只是对单一特征进行了加权,这样我们说不好,因为很多情况下, 特征之间的组合是非常有意义的, 比如“USA”与“Thanksgiving”、“China”与“Chinese New Year”这样的关联特征,对用户的点击有着正向的影响。换句话说,来自“China”的用户很可能会在“Chinese New Year”有大量的浏览、购买行为,而在“Thanksgiving”却不会有特别的消费行为。这种关联特征与label的正向相关性在实际问题中是普遍存在的,如“化妆品”类商品与“女”性,“球类运动配件”的商品与“男”性,“电影票”的商品与“电影”品类偏好等。
那么我们能不能进行特征之间的组合呢?
在逻辑回归里面, 如果想得到组合特征, 往往需要人工在特征工程的时候手动的组合特征, 然后再进行筛选, 但这个比较低效, 第一个是这个会有经验的成分在里面, 第二个是可能会比较玄学, 不太好找到有用的组合特征。 于是乎, 采用POLY2模型进行特征的“暴力”组合就成了可行的选择。 POLY2是二阶多项式模型, 数学形式如下:
看到这个基本上不用怎么解释就明白了, 这个模型对所有的特征进行了两两的交叉, 然后又算得了一个权重, 这个其实和逻辑回归依然是超级像的, 如果我们在逻辑回归中, 做特征工程的时候, 也可以自己做出这样的一些特征来的, 就是所谓的:
1 | for i in range(n-1): |
这样, 其实用逻辑回归再做就相当于那个POLY2的模型了。
但是这个模型会存在两个比较大的问题:
- 推荐系统中的数据往往是非常稀疏的(类别型数据经过独热), 这样会导致特征向量非常的稀疏, 这时候如果再交叉的时候, 往往xi和xj同时不为0的情况很少, 这会导致交叉特征的权重缺乏有效的数据进行训练而无法收敛。 就比如下面这个数据:假设一个广告分类的问题,根据用户和广告位相关的特征,预测用户是否点击了广告(本数据来自美团技术团队分享的paper)
“Clicked?”是label,Country、Day、Ad_type是特征。由于三种特征都是categorical类型的,需要经过独热编码(One-Hot Encoding)转换成数值型特征。
因此, POLY2模型虽然是引入了特征的二阶交叉组合, 但是由于其模型参数, 稀疏场景受限的问题使得FM登场了!
3. FM模型的原理及代码实践
3.1 FM模型的原理
在介绍FM之前, 依然是抛出一个问题, 就是上面的POLY2模型在特征交叉的时候采用的单独的权重, 这使得在稀疏的场景下无法适用, 那么这种问题应该怎么解决呢? 其实, 前面的矩阵分解算法就提供了一种思路—隐向量,还记得矩阵分解吗? 这个是把用户评分矩阵分解成了user矩阵和item矩阵相乘的方式, 即每个user和item都采用了一个隐向量来表示, 如果忘了, 把前面的图拿过来:
这个评分矩阵也是非常稀疏的, 如果采用普通的协同过滤算法, 真的不太好判断用户相似或者物品相似, 但是如果把这个矩阵分解成了两个矩阵相乘的形式, 那么就可以把单独考虑某个用户或者某个物品变成综合考虑所有用户和用品, 基于打分的这些数据就可以得到每个用户和物品的向量, 然后相乘得到最后的评分。
上面的公式中:
这样, 就对上面的公式进行了化简, 方便用梯度下降法求解参数。 但是这个式子最上面那个等式为啥成立呢? 其实, 这个就是矩阵的一个运算化简, 这里用文文大佬画的那个图看一下:
由此可见, FM可以在线性时间训练和预测, 模型非常高效和灵活, 相比后面的深度学习模型复杂的网络结构导致难以部署和线上服务, FM容易实现的模型结构使得线上推断过程相对简单, 也更容易线上部署和服务。 因此, FM在2012-2014前后, 成为了业界主流的推荐模型之一。
3.2 FM模型的代码实战
FM这里的代码实战部分比较丰富, 尝试整理了两种使用FM的思路, 一种是通过pyFM直接掉包, 二是手动实现这个模型。 掉包使用的时候, 我们需要弄清楚这里的FM参数, 还有就是数据集的格式, 必须处理成相应的格式, 否则会报错。 接下来, 尝试整理这两种方式的使用。
实战中的数据集和具体详细代码可以参考最后的GitHub链接,这里只整理重点。 实战部分分为分类和回归, 回归任务用到的数据集是前面协同过滤时电影评分的预测, 而分类任务中的数据集是CBDT+LR里面的criteo CTR数据集, 具体情况参考链接吧。
3.2.1 调包版FM的使用
这个需要调用pyFM这个包, 所以首先需要安装一下这个包。 下面的pyFM包里面介绍了最简单粗暴的pip方法, 但是我按照的有报错提示, 所以这里再提供一种方式:
在https://github.com/coreylynch/pyFM中手动下载包
将包解压,更改里面的setup.py文件,去掉setup.py文件里面的libraries=[“m”]
一行
cd到当前文件夹下python setup.py install
这种方法安装过程中, 如果报C++ 14.0 is required的错误, 那么就再来看这个Microsoft Visual C++ 14.0 is required 的解决方案, 第二种方法亲测了一下。
装好包之后, 我们重点看一下怎么使用, 其实pyFM的GitHub里面也在下面写了几个上手的案例。 如果把人家那个直接复制过来, 就没啥意思了, 这里补充一点别的。掉包版依然是分为回归和分类任务, 关于回归, GitHub项目里面已经给出了电影评分的案例, 这里强调的是输入格式, 一定要按照这个格式来, 否则会报错, 这里它用的是[{'fea1': 'value1', 'fea2': 'value2'}, {}, {}]
的格式, 然后将这个通过DictVectorizer()
进行转换才能用它的包进行训练。 具体的看我给出的GitHub吧, 这里不整理这个。
回归任务
关于回归任务, 这里还是用我前面协同过滤和矩阵分解里面用的那个简单例子, 猜测用户Alice对物品5的打分。这样才有利于把知识连起来嘛,哈哈。
还是这个熟悉的任务, 前面已经用协同过滤和MF完成了一下, 这里我们看看FM如何用于这个任务。通过这个和电影评分的两个, 应该可以使用这个pyFM的包了。 如果要使用FM, 这里和前面两个模型不同的地方就是数据的存储格式, 我们知道协同过滤和矩阵分解都是直接基于这个交互矩阵, 那么在存储的时候往往是用字典, 记录用户对物品评了多少分即可。 但是FM不能直接用这样的数据, 因为FM是把上面这个问题转成一个监督的问题, 监督问题的话就需要特征列和标签。 所以要先把这个数据格式进行一个处理。 具体代码是这样:
1 | # 导入数据这部分还是原来的那个代码 |
这个没变, 为了和原来的保持一致, 但是这里需要处理一下格式:
1 | df = pd.DataFrame(rating_data).T |
这里, 就把数据变成了特征-标签的形式, 这个起作用的是stack函数, 具体的可以参考我整理的另一篇博客。
下面再一步处理, 把item这个进行数字编码, 然后把前两列当做特征, 后一列当做标签划分开数据集:
1 | item_map = {item: str(idx) for idx, item in enumerate(set(df['item']))} |
下面把特征进行one-hot编码, 这里由于是pandas的DataFrame, 我用DictVectorizer()
会报错,所以这里我直接用sklearn的OneHotEncoder()
处理。
1 | one = OneHotEncoder() |
这个处理完是一个稀疏矩阵存储格式, 巧了, 下面的FM还就是用这种格式的, DictVectorizer()
也是处理成这个格式。 长下面这样:
这个OneHotEncoder不过多解释了, 这样每一行的两个特征都用了独热的形式。 下面就是建立FM模型了, 主要是看看这个咋用。
1 | # 建立模型 |
建立模型, 只需要一句话。 但是这里面有好多参数, 我们需要知道
FM的具体参数函数如下: 这里面重点需要设置的我已标出(详细的可以参考源码)
- num_factors: 隐向量的维度, 也就是k
- num_iter: 迭代次数, 由于使用的SGD, 随机梯度下降, 要指明迭代多少个epoch
- k0, k1: k0表示是否用偏置(看FM的公式), k1表示是否要第二项, 就是单个特征的, 这俩默认True
- init_stdev: 初始化隐向量时候的方差, 默认0.01
- validation_size: 验证集的比例, 默认0.01
- learning_rate_schedule: 学习率衰减方式, 有constant, optimal, 和invscaling三种方式, 具体公式看源码
- initial_learning_rate: 初始学习率, 默认0.01
- power_t, t0: 逆缩放学习率的指数,最优学习率分母常数, 这两个和上面学习率衰减方式的计算有关
- task: 分类或者回归任务, 要指明
- verbose: 是否打印当前的迭代次数, 训练误差
- shuffle_training: 是否在学习之前打乱训练集
- seed: 随机种子
建立了模型之后, 下面训练和预测就非常简单, 还是fit
和predict
.
1 | # 模型训练 |
这样就用FM完成了之前预测用户商品评分的例子, 看懂了这个再看它给的电影评分的例子就会非常简单了。
分类任务
调包完成分类任务, pyFM GitHub里面给出了一个随机生成的数据集完成分类, 这里为了衔接下面的造轮子的内容, 用调包的方式在criteo数据集进行实战。这里非常重要的一个点依然是数据的格式。如果处理不当, 就无法用人家的包训练。首先是导入数据集, 并简单处理, 这部分代码直接用的GBDT+LR里面的代码, 与前面的衔接。
1 | # 数据读取 |
下面进行类别特征的编码, 这里用LabelEncoder()
,并生成数据集
1 | # 类别特征编码 |
下面是进行数据归一化, 因为我发现如果不归一化, 下面训练的时候会出现loss为nan
1 | # 标准化 |
下面是最关键的一部, 转换格式, 这也是我花最多时间探索的一步, 需要这种格式:
1 | # 转换格式 [{'0': 'value', '1': 'value', }, {}, {}...{}], 这样的格式, 一个列表, 然后里面元素是字典表示每个样本, 字典的键是特征的索引下标, 值是特征值 |
下面就是建立模型了:分类任务, 注意task参数
1 | # 建立模型 |
3.2.2 造轮子版FM
造轮子版来自于Datawhale的推荐系统组队学习, 如意哥写的, 向大佬学习了一下这个代码, 这个是通过keras写的, 也是用的criteo的数据集, 所以和上面正好又对起来。 思路就是读入数据之后, 特征编码, 然后构建FM的组合层, 写成了类似神经网络的那种形式。不是太难理解, 下面一块块的来看:
1 | # dense特征取对数, sparse特征类别编码 |
这个函数的作用就是完成编码, 数值特征用了对数转换, 类别特征LabelEncoder()
编码。 下面就是FM的造轮子实现:
1 | # FM 特征组合层 |
这里首先, 自定义了一个交叉特征的层, 完成的是公式里面的第三部分运算。 self.kernel
就是w矩阵,和上面的公式唯一不同的就是这里统一采用了矩阵运算的形式。 应该比较好理解。
1 | # 定义FM模型 |
这里定义了FM模型, 这个就是完全是实现了FM的公式。 一阶特征部分是一个Dense层, 二阶特征交叉就是上面定义的那个层, 最后Add()连接, 再用sigmoid激活。 这里我也是新学到的这种思路, 竟然可以这样写, interesting 😉. 后面就是常规操作了, 一块写下来吧:
1 | # 读入数据 |
关于FM的实战部分, 目前就学了这么多, 所以先整理到这里吧, 具体详细代码和数据集, 可以去后面的GitHub。
3.3 FM模型的应用
最直接的想法就是直接把FM得到的结果放进sigmoid中输出一个概率值,由此做CTR预估,事实上我们也可以做召回。
由于FM模型是利用两个特征的Embedding做内积得到二阶特征交叉的权重,那么我们可以将训练好的FM特征取出离线存好,之后用来做KNN向量检索。
工业上, 应用FM的具体操作步骤:
- 离线训练好FM模型(学习目标可以是CTR)
- 将训练好的FM模型Embedding取出
- 将每个uid对应的Embedding做avg pooling(平均)形成该用户最终的Embedding,item也做同样的操作
- 将所有的Embedding向量放入Faiss等
- 线上uid发出请求,取出对应的user embedding,进行检索召回
关于工业上的更多应用, 这里先占个坑, 等探索完了,后面会再来补充。
4. FFM模型的原理及代码实践
2015年, 基于FM提出的FFM在多项CTR预估大赛中夺魁, 并被Criteo、美团等公司深度应用在推荐系统、CTR预估等领域, 相比于FM模型, FFM模型引入了特征域感知(filed-aware) 这个概念, 使得模型的表达能力更强。 下面就来看看这个模型的原理。
4.1 FFM模型的原理
既然这个模型是基于FM模型, 那么应该是从FM模型上面进行的改进, 那么回顾上面的FM模型, 哪个地方会存在问题呢? FM的模型公式如下:
说得对, 就是后面的这个权重计算。 就拿上面的那个例子来看:
那么, 我们为啥不先把特征先分一下类(因为很多都是one-hot之后的特征嘛, 就比如上面的Day, Ad_type, 这些特征其实是可以属于一类总体的日期类或者广告类型类), 然后对于每个特征, 我们按照不同的域学习不同的隐向量呢? 也就是一个特征对应多个隐向量。 这样在与不同域(类)里面特征交叉的时候, 用相应的隐向量去交叉计算权重, emmm, 这倒是一种思路, 并且这样做的好处是学习隐向量的时候只需要考虑相应的域的数据, 且与不同类的特征进行关联采用不同的隐向量, 这和不同类特征的内在差异也比较相符。 这其实就是FFM在FM的基础上做的改进, 引入了域的概念, 对于每个特征, 针对不同的交叉域要学习不同的隐向量特征。
这里的域理解起来的话其实就是先对特征根据性质的不同进行了一个分类,不同的分类就是不同的域,域内特征一般都是同一个categorical特征经过One-Hot编码生成的数值特征,比如用户性别, 职业, 日期啊等等。比如:
对于连续特征, 一个特征就对应一个域, 或者可以对连续特征离散化, 一个分箱成为一个特征, 总的分箱是一个域。 对于离散特征, 就像上面说的, 采用one-hot编码, 同一种属性的归到一个域。 工业上, 一般用的这种具有物理意义上的真实特征或者域的个数一般是100-150个。
这里再进行一点知识的串联, 很多东西虽然猛地一看,感觉八竿子打不着, 但是细品的话, 会看到一些相似的东西,比如word2vec, 我们进行word2vec学习词向量的时候,其实也用了类似于这种思想, 那里也是有两个W矩阵的, 第一个W矩阵是每个单词作为中心词学习出的embedding矩阵, 第二个W矩阵是每个单词作为上下文词学习出的embedding矩阵。 也会发现,不同单词不同身份的时候,会有不同的embedding对待, 其实这里的FFM域embedding,有异曲同工之妙。
好了, 如果经过上面的铺垫感觉FFM差不多了, 那么下面就是模型的方程了:
这里可以和FM进行一个对比, 其实就是权重计算的那块变了。
下面先用文文大佬的一个例子看一下FFM的特征组合方式, 然后简单的推导一下上面这个方程具体怎么学习求参数。
假设输入记录如下:
这条记录可以编码成5个特征,其中“Genre=Comedy”和“Genre=Drama”属于同一个field,“Price”是数值型,不用One-Hot编码转换。为了方便说明FFM的样本格式,我们将所有的特征和对应的field映射成整数编号。
其中,红色是field编号,蓝色是特征编号。
下面来讨论FFM的具体训练细节, 我们依然会使用梯度下降来更新参数, 那么涉及到的一点依然是求导。 看看FFM这里如何求导。关于公式的前面两部分, 和FM一样, 这里不说了, 主要是蓝色的那一部分, 拿下来单独看:
但有了上面的推导过程, 这个应该很好理解了。无非就是损失函数换了换样子, 穿了另一个马甲而已 😉
工业上, 原始的FFM一般不会使用, 因为这哥们计算量太大了, 每个域都会学习特征, 这个与word2vec做个对比,那里每个单词只有两个身份, 这时候,对应了2个embedding矩阵, 而这里假设有100个域, 那么相当于每个实值特征有99个身份(会和其他99个域特征交叉), 这时候99个embedding矩阵, 而每个embedding矩阵维度就很大了, 这样的计算更新是受不了的。如果真想用,一般要做一些处理, 两个改进的思路:
- model上:双线性FFM(新浪微博张俊林团队)–减少参数量的一种优化思路,共享W矩阵, 有些公司已经尝试开始用。
- 业务上:大部分公司都采用这个方式,就是域再进行抽象和升华,这样就可以减少域的数量了, 比如说, 上面说了100域或者说100特征, 这100个特征分类一下,大致上分为上下文特征, 用户特征, item特征,交互特征和匹配特征五大类, 而真正域交叉的时候,考虑着5类特征或者身份即可。 这样就相当于每个实值特征有5个身份了(会和与自己同类的特征,其他类的特征交互), 这样就只有5个embedding矩阵了,相比上面的99个可就大大减少参数量和计算量了。 这是一种退而求其次的方式。
工业上, 一般FFM确实很少用,召回和排序部分都不是首选FFM模型, 但是FM模型还是非常重要的, 基本上业界首选。下面简单总结下:
- 做召回的话一般先考虑策略,tag,热度的召回,然后再是模型,召回模型常用的双塔,FM, 协同(MF) 这个还是很有用的。
- 做文章推荐的时候, 排序模型首选LR, 然后FM, DeepFM,然后多目标。一般GBDT+LR也不是太考虑,因为它的效果和FM类似,不如直接FM省事, 前者更新起来太复杂。 如果是电商广告推荐, 最后还要试试DIN这种模型。
4.2 FFM模型的代码实战
关于FFM的代码实战, 这里参考了下面的FFM代码实现, 这个是从头手撸了一个, 在这里简单的整理一下我学习到的一些思想吧, 具体可以参考下面链接的分析。
首先,FFM模型的话, 需要的数据是有格式要求的, 一般是存储稀疏矩阵, 且格式会是
所以, 在代码具体实现中, 把这种一一看成了链表节点的形式, 所以一开始定义了一个FFM_Node
1 | class FFM_Node(object): |
这个类就是以元组的形式储存数据, 方便后面的操作。 FFM模型具体实现的时候, 这个和FM不一样的就是这里没法先将公式化简, 然后使用向量运算一步到位, 对于交叉特征, 这里只能写两重循环去实现。所以看看FFM这个模型具体实现的时候, 需要哪些自己的属性:
1 | def __init__(self, m, n, k, eta, lambd): |
比较核心的就是域的个数, 特征的个数, 隐向量的维度, w矩阵。 学习率和lambda是和训练相关的参数, 而G这个是采用了Adagrad算法, 这里面更新的时候要用到。 下面看一下前向传播, 要注意那个两层的循环计算权重, 这里其实是FFM的核心部分了:
1 | # 这个是计算第三项 |
这里只计算的公式里面的第三项, 传入参数是node_list, 也就是所有的数据都以链表的形式穿起来了。当然具体实现的时候一个列表即可。 这里应该不用过多解释, 就是严格按照FFM的计算公式算的第三项。 下面再来看看反向传播, 也就是求导数的过程, 这里用的随机梯度下降:
1 | # 随机梯度下降 |
这个代码从远处看或许比较复杂, 但思路依然不难, 我们是先要求各个交叉项参数的导数, 然后根据梯度下降公式更新参数。 求导数, 根据上面推导的公式, 就会一目了然。
唯一不一样的时候,就是求出导数之后, 参数的更新方式, 这里用的Adagrad算法。
这里就把FFM具体实现过程中的细节整理了一下, 更多的参考下面的链接吧。文文大佬还给了一个TensorFlow版本的, 也可以参考一下计算方式。
5. 总结
这篇文章也是用了一周的时间整理, 因为推荐这边的文章也是现学现卖哈哈, 所以难免会有疏漏或者理解错误之处, 还请各位伙伴如果发现了即使指正。 这篇文章由于涉及到了两个模型, 所以篇幅还是比较长, 依然是各取所需即可。
下面简单的梳理一下这篇文章和推荐系统深度学习的前夜模型。 这篇文章是深度学习前夜里面的最后一篇, 主要是围绕着两个模型FM和FFM模型展开, 逻辑非常清楚, 首先是先抛出了之前的逻辑回归存在的手动交叉特征的问题, 从而先整理了POLY2模型的思路,也就是二项交叉,但是这个模型会有一些不足, 分析了一下, 然后引出了FM模型, 整理了FM模型的原理及代码实践部分。 接着在FM的基础上进行了扩展, 得到了FFM模型, 又整理了FFM模型的原理及代码实践部分。
不知不觉,从开始学习推荐系统到现在,用了大约不到1个月的时间吧, 已经过了一遍前深度学习模型时代的四五个比较重要的Model和代码, 并整理了四篇文章。 虽然花费了很多时间, 但收获很大, 并且这次亲自体验了一下任务驱动的学习方式, 确实效率会高一些(这次有幸参与了Datawhale10月推荐系统组队的文档编写任务), 下面简单的回顾一下前深度学习时代这四篇文章之间的联系
这次是按照王喆老师梳理好的这个框架进行的展开的, 逻辑应该是一目了然, 这里不再啰嗦了, 还有一个LS-PLM模型, 这个曾是阿里的主流推荐模型, 当然也是2017年以前了吧, 再这里没有具体详细整理, 这个模型是在逻辑回归的基础上采用了分而治之的思想, 先对样本进行分组(聚类), 再在样本中使用逻辑回归。因为有时候, 用户群里的类别不同, 行为会有很大的不同,比如男性往往喜欢数码产品, 而女性往往喜欢衣服等。 那么这时候, 考虑用户点击数码广告的时候, 往往不用把女性点击衣服等行为考虑进来, 因为这些和目标相关性不大, 所以为了让CTR模型对不同用户群体, 不同使用场景更有针对性, 阿里就提出了LS-PLM模型, 先对全量样本进行聚类, 再对每个分类用逻辑回归完成CTR预估, 这其实是提供了另外一种新思路,因为模型可不一定非得逻辑回归哟, 这些处理问题的idea往往是我们需要学习的。这个模型已经有了深度学习的味道, 类似于一个加入注意力机制的三层神经网络模型。 当然具体的细节还是看王喆老师的那本书吧。 下面是模型的大总结:
关于前深度学习时代的模型, 就先到这里了, 下面就是深度学习的浪潮之巅了, 这里面才更能体会到这几年深度学习对于推荐系统发展的驱动, 2016年开始, 推荐系统进入了深度学习的浪潮,至今为止, 依然高速发展。 最后, 再梳理一下时间线:
后面依然是保持一周更新一个推荐模型, 因为根据这四篇文章大体算了一下, 由于也是刚学这些知识, 所以整理的时候,一般需要先从原论文开始, 到参考很多优质的文章, 再到代码实践部分, 每天去除掉其他任务的一些时间, 感觉五天学习, 周末整理刚刚好哈哈,下面继续Rush吧 😉
参考:
- 王喆 - 《深度学习推荐系统》
- 推荐系统遇上深度学习(一)–FM模型理论和实践
- 推荐系统遇上深度学习(二)–FFM模型理论和实践
- FM算法解析
- FM算法原理分析与实践
- 深入理解FFM原理与实践
- FFM原理及公式推导
- FM在特征组合中的应用
- FFM算法解析及Python实现
- FFM代码实现
- pyFM包
- 文文大佬的GitHub
论文:
- FM论文原文
- FFM论文原文
整理这篇文章的同时, 也刚建立了一个GitHub项目, 准备后面把各种主流的推荐模型复现一遍,并用通俗易懂的语言进行注释和逻辑整理, 今天的FM+FFM模型代码已经上传,感兴趣的可以看一下 😉
筋斗云:https://github.com/zhongqiangwu960812/AI-RecommenderSystem