全文共1979字,6张图,预计阅读时间12分钟。

FFM理论

在CTR预估中,经常会遇到one-hot类型的变量,one-hot类型变量会导致严重的数据特征稀疏的情况,为了解决这一问题,在上一讲中,我们介绍了FM算法。这一讲我们介绍一种在FM基础上发展出来的算法-FFM(Field-aware Factorization Machine)。

FFM模型中引入了类别的概念,即field。还是拿上一讲中的数据来讲,先看下图:

在上面的广告点击案例中,“Day=26/11/15”、“Day=1/7/14”、“Day=19/2/15”这三个特征都是代表日期的,可以放到同一个field中。同理,Country也可以放到一个field中。简单来说,同一个categorical特征经过One-Hot编码生成的数值特征都可以放到同一个field,包括用户国籍,广告类型,日期等等。

在FFM中,每一维特征 xi,针对其它特征的每一种field fj,都会学习一个隐向量 v_i,fj。因此,隐向量不仅与特征相关,也与field相关。也就是说,“Day=26/11/15”这个特征与“Country”特征和“Ad_type"特征进行关联的时候使用不同的隐向量,这与“Country”和“Ad_type”的内在差异相符,也是FFM中“field-aware”的由来。

假设样本的 n个特征属于 f个field,那么FFM的二次项有 nf个隐向量。而在FM模型中,每一维特征的隐向量只有一个。FM可以看作FFM的特例,是把所有特征都归属到一个field时的FFM模型。根据FFM的field敏感特性,可以导出其模型方程。

可以看到,如果隐向量的长度为 k,那么FFM的二次参数有 nfk 个,远多于FM模型的 nk个。此外,由于隐向量与field相关,FFM二次项并不能够化简,其预测复杂度是 O(kn^2)。

下面以一个例子简单说明FFM的特征组合方式。输入记录如下:

这条记录可以编码成5个特征,其中“Genre=Comedy”和“Genre=Drama”属于同一个field,“Price”是数值型,不用One-Hot编码转换。为了方便说明FFM的样本格式,我们将所有的特征和对应的field映射成整数编号。

那么,FFM的组合特征有10项,如下图所示。

其中,红色是field编号,蓝色是特征编号。

FFM实现细节

这里讲得只是一种FFM的实现方式,并不是唯一的。

损失函数

FFM将问题定义为分类问题,使用的是logistic loss,同时加入了正则项

什么,这是logisitc loss?第一眼看到我是懵逼的,逻辑回归的损失函数我很熟悉啊,不是长这样的啊?其实是我目光太短浅了。逻辑回归其实是有两种表述方式的损失函数的,取决于你将类别定义为0和1还是1和-1。大家可以参考下下面的文章:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/6340129.html。当我们将类别设定为1和-1的时候,逻辑回归的损失函数就是上面的样子。

随机梯度下降

训练FFM使用的是随机梯度下降方法,即每次只选一条数据进行训练,这里还有必要补一补梯度下降的知识,梯度下降是有三种方式的,截图取自参考文献3:

总给人一种怪怪的感觉。batch为什么是全量的数据呢,哈哈。

TensorFlow实现代码

本文代码的github地址:
https://github.com/princewen/tensorflow_practice/tree/master/recommendation-FFM-Demo

这里我们只讲解一些细节,具体的代码大家可以去github上看:

生成数据

这里我没有找到合适的数据,就自己产生了一点数据,数据涉及20维特征,前十维特征是一个field,后十维是一个field:

def gen_data():labels = [-1,1]y = [np.random.choice(labels,1)[0] for _ in range(all_data_size)]x_field = [i // 10 for i in range(input_x_size)]x = np.random.randint(0,2,size=(all_data_size,input_x_size))return x,y,x_field

定义权重项

在ffm中,有三个权重项,首先是bias,然后是一维特征的权重,最后是交叉特征的权重:

def createTwoDimensionWeight(input_x_size,field_size,vector_dimension):weights = tf.truncated_normal([input_x_size,field_size,vector_dimension])

tf_weights = tf.Variable(weights)

return tf_weights

def createOneDimensionWeight(input_x_size):weights = tf.truncated_normal([input_x_size])tf_weights = tf.Variable(weights)return tf_weights

def createZeroDimensionWeight():weights = tf.truncated_normal([1])tf_weights = tf.Variable(weights)return tf_weights

计算估计值

估计值的计算这里不能项FM一样先将公式化简再来做,对于交叉特征,只能写两重循环,所以对于特别多的特征的情况下,真的计算要爆炸呀!

def inference(input_x,input_x_field,zeroWeights,oneDimWeights,thirdWeight):"""计算回归模型输出的值"""

secondValue = tf.reduce_sum(tf.multiply(oneDimWeights,input_x,name='secondValue'))

firstTwoValue = tf.add(zeroWeights, secondValue, name="firstTwoValue")

thirdValue = tf.Variable(0.0,dtype=tf.float32)input_shape = input_x_size

for i in range(input_shape):featureIndex1 = IfieldIndex1 = int(input_x_field[I])for j in range(i+1,input_shape):    featureIndex2 = j    fieldIndex2 = int(input_x_field[j])    vectorLeft = tf.convert_to_tensor([[featureIndex1,fieldIndex2,i] for i in range(vector_dimension)])    weightLeft = tf.gather_nd(thirdWeight,vectorLeft)    weightLeftAfterCut = tf.squeeze(weightLeft)

    vectorRight = tf.convert_to_tensor([[featureIndex2,fieldIndex1,i] for i in range(vector_dimension)])    weightRight = tf.gather_nd(thirdWeight,vectorRight)    weightRightAfterCut = tf.squeeze(weightRight)

    tempValue = tf.reduce_sum(tf.multiply(weightLeftAfterCut,weightRightAfterCut))

    indices2 = [I]    indices3 = [j]

    xi = tf.squeeze(tf.gather_nd(input_x, indices2))    xj = tf.squeeze(tf.gather_nd(input_x, indices3))

    product = tf.reduce_sum(tf.multiply(xi, xj))

    secondItemVal = tf.multiply(tempValue, product)

    tf.assign(thirdValue, tf.add(thirdValue, secondItemVal))

return tf.add(firstTwoValue,thirdValue)

定义损失函数

损失函数我们就用逻辑回归损失函数来算,同时加入正则项:

lambda_w = tf.constant(0.001, name='lambda_w')lambda_v = tf.constant(0.001, name='lambda_v')

zeroWeights = createZeroDimensionWeight()

oneDimWeights = createOneDimensionWeight(input_x_size)

thirdWeight = createTwoDimensionWeight(input_x_size,  # 创建二次项的权重变量                               field_size,                               vector_dimension)  # n * f * k

y_ = inference(input_x, trainx_field,zeroWeights,oneDimWeights,thirdWeight)

l2_norm = tf.reduce_sum(tf.add(tf.multiply(lambda_w, tf.pow(oneDimWeights, 2)),tf.reduce_sum(tf.multiply(lambda_v, tf.pow(thirdWeight, 2)),axis=[1,2])))

loss = tf.log(1 + tf.exp(input_y * y_)) + l2_norm

train_step =tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(loss)

训练

接下来就是训练了,每次只用喂一个数据就好:

input_x_batch = trainx[t]input_y_batch = trainy[t]predict_loss,_, steps = sess.run([loss,train_step, global_step],                 feed_dict={input_x: input_x_batch, input_y: input_y_batch})

跑的是相当的慢,我们来看看效果吧:

参考文章

参考文章

1、https://tech.meituan.com/deep-understanding-of-ffm-principles-and-practices.html

2、https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/6340129.html

3、https://www.cnblogs.com/pinard/p/5970503.html

原文链接:https://mp.weixin.qq.com/s/Mp1eYfxbhUTZcJs_3cwQNg

查阅更为简洁方便的分类文章以及最新的课程、产品信息,请移步至全新呈现的“LeadAI学院官网”:

www.leadai.org

请关注人工智能LeadAI公众号,查看更多专业文章

大家都在看

LSTM模型在问答系统中的应用

基于TensorFlow的神经网络解决用户流失概览问题

最全常见算法工程师面试题目整理(一)

最全常见算法工程师面试题目整理(二)

TensorFlow从1到2 | 第三章 深度学习革命的开端:卷积神经网络

装饰器 | Python高级编程

今天不如来复习下Python基础

推荐系统遇上深度学习(二)--FFM模型理论和实践相关推荐

  1. 推荐系统遇上深度学习(八)--AFM模型理论和实践

    预计阅读时间10分钟. 引言 在CTR预估中,为了解决稀疏特征的问题,学者们提出了FM模型来建模特征之间的交互关系.但是FM模型只能表达特征之间两两组合之间的关系,无法建模两个特征之间深层次的关系或者 ...

  2. 推荐系统遇上深度学习(一)--FM模型理论和实践

    全文共2503字,15张图,预计阅读时间15分钟. FM背景 在计算广告和推荐系统中,CTR预估(click-through rate)是非常重要的一个环节,判断一个商品的是否进行推荐需要根据CTR预 ...

  3. 推荐系统遇上深度学习(七)--NFM模型理论和实践

    预计阅读时间10分钟. 引言 在CTR预估中,为了解决稀疏特征的问题,学者们提出了FM模型来建模特征之间的交互关系.但是FM模型只能表达特征之间两两组合之间的关系,无法建模两个特征之间深层次的关系或者 ...

  4. 推荐系统遇上深度学习(六)--PNN模型理论和实践

    全文共2621字,21张图,预计阅读时间15分钟. 原理 PNN,全称为Product-based Neural Network,认为在embedding输入到MLP之后学习的交叉特征表达并不充分,提 ...

  5. 知识图谱论文阅读(八)【转】推荐系统遇上深度学习(二十六)--知识图谱与推荐系统结合之DKN模型原理及实现

    学习的博客: 推荐系统遇上深度学习(二十六)–知识图谱与推荐系统结合之DKN模型原理及实现 知识图谱特征学习的模型分类汇总 知识图谱嵌入(KGE):方法和应用的综述 论文: Knowledge Gra ...

  6. 推荐系统遇上深度学习(二十二):DeepFM升级版XDeepFM模型强势来袭!

    今天我们要学习的模型是xDeepFM模型,论文地址为:https://arxiv.org/abs/1803.05170.文中包含我个人的一些理解,如有不对的地方,欢迎大家指正!废话不多说,我们进入正题 ...

  7. 推荐系统遇上深度学习(二十)--探秘阿里之完整空间多任务模型ESSM

    笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值不仅仅只体现在企业中,个人也可以体会到数据的魅力,用技术力量探索行为密码,让大数据 ...

  8. 推荐系统遇上深度学习(二十六)--知识图谱与推荐系统结合之DKN模型原理及实现

    作者:石晓文 Python爱好者社区专栏作者个人公众号:小小挖掘机 添加微信sxw2251,可以拉你进入小小挖掘机技术交流群哟!博客专栏:wenwen 在本系列的上一篇中,我们大致介绍了一下知识图谱在 ...

  9. 推荐系统遇上深度学习(二十)-贝叶斯个性化排序算法原理及实战

    排序推荐算法大体上可以分为三类,第一类排序算法类别是点对方法(Pointwise Approach),这类算法将排序问题被转化为分类.回归之类的问题,并使用现有分类.回归等方法进行实现.第二类排序算法 ...

最新文章

  1. python快捷方式图标_python – PyInstaller无法更改快捷方式图标
  2. Jquery简单的右侧浮动菜单
  3. 【华为云技术分享】使用sqoop导入mysql数据到hive中
  4. 零基础带你学习MySQL—多表查询笛卡尔集(二十)
  5. 你的关注,就是我的动力!(第3次改版中)
  6. R语言预测初步(R语言预测实战-节选)
  7. 第一行代码笔记-第五章
  8. 2021必收藏!Java编程技巧之单元测试用例编写流程
  9. 邱锡鹏神经网络怎么样,邱锡鹏神经网络答案
  10. 宝尚网上开户踏准板块轮动节奏的机会
  11. 整理大数据相关的内容,包括博客、笔试真题、项目、面经。希望能帮到想往大数据方向发展的从业人员
  12. MySQL8pdf_Mysql8.0中文参考手册 中英文chm+pdf版
  13. 《精益创业》读书笔记
  14. linux透明桥,linux透明防墙(网桥模式).doc
  15. nvm use报错exit status 1解决方法
  16. 国外计算机核心期刊易读,国内英语写作研究现状的文献综述——对十大外语类核心期刊近五年(2012-2016)的统计分析...
  17. 成功源于勤奋--起点年薪20万作者奋斗史
  18. iOS锁屏界面音频播放控制
  19. PHP 图片处理类(水印、透明度、缩放、相框、锐化、旋转、翻转、剪切、反色)...
  20. 常见互联网公司职级和薪资一览!

热门文章

  1. python组件化软件github_GitHub - 872409/wepy: 小程序组件化开发框架
  2. java roundingmode.UP,即使明确设置,DecimalFormat也使用不正确的RoundingMode
  3. disable path length limit_通过Antsword看绕过disable_functions
  4. python第一周小测验_测验1: Python基本语法元素 (第1周)-程序题
  5. 量化延时法时间测量_干货分享:直线度测量发展及几种方法详解
  6. 【Linux】kali2019安装docker
  7. 以太网实习_从最初有从事IT的想法,到现在实习两个月的感受
  8. python面向对象编程98讲_谈面向对象的编程(Python)
  9. bi工具选型_数据分析工具:选合适了,分析也能事半功倍
  10. 部门管理系统_什么是实物资产管理系统?优势有哪些?