理论:FM理论解析及应用

FM的产生背景

我其实没有做过很多ctr预估的事情,但是我在工作中常常遇到CRM流失预估、订单预估这些依赖于特征工程的事情,其中就涉及到特征的组合问题。

one-hot过程

在feature选取过程中,不可避免的会出现,学历这种高中、大学、研究生等多分类的feature,在实际应用中,我们对单个feature需要进行一种one hot过程,就是将原来的学历拆解为 是否为高中,是否为大学,注意,可以不用加是否为研究生一列,因为是否为高中,是否为大学的两列已经可以推导这个用户是否为研究生,加上这一列有时候反而会共线性。但是这样做,看起来没什么问题,想想看要是100个这样的特征,每个特征有100个这样单独的feature value的话,整体数据将是一个非常庞大的稀疏矩阵,无论是计算还是分析都是会存在巨大的问题的,所以看看我们能不能组合一些特征降低维度。

什么叫做组合问题

现在有一组数据,其中特征包含性别(男女),学历(高中,大学,研究生),想要判断这两个feature对是否对化妆品感谢兴趣。单独的观察性别这一栏,发现有一定相关性,但是比较弱,并不是所有的女性都对化妆品感兴趣;单独的观察学历这一栏也发现,学历与对化妆品感兴趣的程度并没有显著的相关性。其实,我们可以从自己的感知理解,首先,数据中女生可能比男生对化妆品更感兴趣,但是女生数据中存在大量的高中生,相对于高中生而言,大学生和研究生可能对化妆品更加感兴趣一点,所以原来的两个feature:性别,学历就组合成了是否为性别女+学历大于高中一个feature,这就是特征组合的过程。如果feature总个数少还可以,要是要有上千上万个,光两两组和就有n*(n-1)/2种可能,所以我们需要想一个其他办法。

组合特征后的表达形式

首先,我们都知道一般的线性模型为:


为了考虑组合特征的作用,我们采用多项式来代表,形如特征xi与xj的组合用xixj表示,具体的表达式如下:



其中,wij为组合特征xixj的权重,n表示样本的feature个数,xi为第I个feature。

方程定义完成了,下面就要开始数学定义

对每一个特征xi引入辅助向量Vi=(vi1,vi2,...vik),这边的k就是矩阵拆解的规模值,利用Vi*Vj.T对交叉项的系数wij进行估计,




这边需要注意一点,k理论上讲,越大越能强化拟合的能力,但是实际在运算过程中,一来受限于计算能力,二来受限于数据量,过大的k只会带来过拟合的问题。我实测了40w作用的数据,观察到k值在6-8左右,valid集合数据拟合效果最优,仅供参考

很明显,上面这么多未知数:1+n是线性未知数个数,nfeature是组合特征的未知数个数,常规求解的效率可想而知。但是看到xixj这样的形式,我们很容易联想到:2ab = (a+b)^2 -a^2 -b^2,所以在解决这个wij、xi、xj点积的问题上,我们采用了:1/2 * ( (a+b+c)^2 - a^2 - b^2 - c^2)的方式


下面让我们来解这个式子

这边需要一点导数功底,我们先来看对w0也就是bias求导,这个毫无意外,梯度为1;再对wi求导,这个也很简单,xi即可,这个也很简单,少许繁琐的就是wij求导,让我来仔细看看:



ok,我知道我的字很丑,别说话,看问题,所以我们可以总结为下面这个网上到处都有的式子:



这个式子就是上面这么来的。
把上面的那个点积形式代入求解及为:

引申一个FFM概念

在FM模型中,每一个特征会对应一个隐变量,但在FFM模型中,认为应该将特征分为多个field,每个特征对应每个field分别有一个隐变量。

举个例子,我们的样本有3种类型的字段:qualifications, age, gender,分别可以代表学历,年龄段,性别。其中qualifications有3种数据,age有5种数据,gender有男女2种,经过one-hot编码以后,每个样本有7个特征,其中只有3个特征非空。
如果使用FM模型,则7个特征,每个特征对应一个隐变量。
如果使用FFM模型,则7个特征,每个特征对应3个隐变量,即每个类型对应一个隐变量,及对应qualifications, age, gender各占一个。

我看了Yu-Chin Juan实现了一个C++版的FFM模型的源码,倒过来想他的表达式应该是这样的:



其他模块都与fm差不多,主要看Vj1f2Vj2f1这个东西。我们假设j1特征属于f1这个field,j2特征属于f2这个feild,则Vj1f2表示j1这个特征对应j2所属的field的隐变量。很恶心的解释,通俗的来讲就是,性别为女与学历这个field的组合有个隐变量,性别女与年龄这个field的组合又有一个不一样的隐变量,而却不考虑到底是什么学历是啥,年龄具体到什么细节。
Yu-Chin Juan大神在实际写code的过程中,干掉来常数和一次项,可能是为了方便计算,保留的如下:



整理的最优化损失函数如下:

前面为l2正则,后面为交互熵形式,注意这边的y属于{-1,1}
这边的求导,我算了一个小时都没搞出来,等哪天有空了,再仔细的去算一下,最后的迭代形式如下:



η是常规的速率,V是初始均匀分布即可

代码实现

我这边完成了FM的代码实现,详细见我的github:fm代码
为了方便不想看细节,只想撸代码的同学,我打包上传到了pypi,你只需要pip install Fsfm即可体验
至于ffm,我下午实在没写出来,对不起彭老师,给你教的数分丢脸了,后续看什么时候有空再研究一下。
最后,着重提示,本文很多思路很解析都参考的Yu-Chin Juan的源代码,附上github地址,欢迎去关注原作者的内容,感谢大神带路,谢谢大家阅读。


欢迎大家关注我的个人bolg,更多代码内容欢迎follow我的个人Github,如果有任何算法、代码疑问都欢迎通过公众号发消息给我哦。

少年,扫一下嘛

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342