FM、FFM以及DeepFM

2024-04-14 08:12
文章标签 fm deepfm ffm

本文主要是介绍FM、FFM以及DeepFM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

FM部分

  • 什么是FM
    FM是factor machine的简写,中文翻译为因子分解机。
  • 为什么需要FM
    在进行特征建模的过程中,经常会遇到两种情况:
    1. 对特征直接进行建模,未考虑特征之间的关联信息;
    2. 特征高维稀疏,导致计算量大,特征权值更新缓慢;
      FM正好能解决特征交互问题;另外FM 通过引入隐向量,能够降低稀疏特征的维度;提高交互特征参数评估;
  • FM长啥样
    1. 在这里插入图片描述
    2. 特征组合
      在这里插入图片描述
      矩阵分解提供了一种解决思路。在model-based的协同过滤中,一个rating矩阵可以分解为user矩阵和item矩阵,每个user和item都可以采用一个隐向量表示。比如在下图中的例子中,我们把每个user表示成一个二维向量,同时把每个item表示成一个二维向量,两个向量的点积就是矩阵中user对item的打分。
      上图中n个user,经过one-hot编码,变成n1n维,属于高度稀疏矩阵;为了减少维度,可以通过引入隐向量,将每个user映射为k维,则特征矩阵维度变为n1k维,即上图中的表示形式。

类似地,所有二次项参数 <Vi,Vj>可以组成一个对称阵 W(为了方便说明FM的由来,对角元素可以设置为正实数),那么这个矩阵就可以分解为 W=Vt*V,V 的第 j列( vj)便是第 j维特征( xj)的隐向量。换句话说,特征分量xj 和xi 的交叉项系数就等于xi对应的隐向量与xj对应的隐向量的内积,即每个参数 wij=<vi,vj>,这就是FM模型的核心思想。
关于隐向量,这里的 vi是xi 特征的低纬稠密表达,实际中隐向量的长度通常远小于特征维度N,在我做的实验中长度都是4。在实际的CTR场景中,数据都是很稀疏的category特征,通常表示成离散的one-hot形式,这种编码方式,使得one-hot vector非常长,而且很稀疏,同时特征总量也骤然增加,达到千万级甚至亿级别都是有可能的,而实际上的category特征数目可能只有几百维。FM学到的隐向量可以看做是特征的一种embedding表示,把离散特征转化为Dense Feature,这种Dense Feature还可以后续和DNN来结合,作为DNN的输入,事实上用于DNN的CTR也是这个思路来做的。

  • FM应用场景
    在这里插入图片描述

  • FM code实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

# -*- coding: utf-8 -*-from __future__ import division
from math import exp
from numpy import *
from random import normalvariate  # 正态分布
from sklearn import preprocessing
import numpy as np'''data : 数据的路径feature_potenital : 潜在分解维度数alpha : 学习速率iter : 迭代次数_w,_w_0,_v : 拆分子矩阵的weightwith_col : 是否带有columns_namefirst_col : 首列有价值的feature的index
'''class fm(object):def __init__(self):self.data = Noneself.feature_potential = Noneself.alpha = Noneself.iter = Noneself._w = Noneself._w_0 = Noneself.v = Noneself.with_col = Noneself.first_col = Nonedef min_max(self, data):self.data = datamin_max_scaler = preprocessing.MinMaxScaler()return min_max_scaler.fit_transform(self.data)def loadDataSet(self, data, with_col=True, first_col=2):# 我就是闲的蛋疼,明明pd.read_table()可以直接度,非要搞这样的,显得代码很长,小数据下完全可以直接读嘛,唉~self.first_col = first_coldataMat = []labelMat = []fr = open(data)self.with_col = with_colif self.with_col:N = 0for line in fr.readlines():# N=1时干掉列表名if N > 0:currLine = line.strip().split()lineArr = []featureNum = len(currLine)for i in range(self.first_col, featureNum):lineArr.append(float(currLine[i]))dataMat.append(lineArr)labelMat.append(float(currLine[1]) * 2 - 1)N = N + 1else:for line in fr.readlines():currLine = line.strip().split()lineArr = []featureNum = len(currLine)for i in range(2, featureNum):lineArr.append(float(currLine[i]))dataMat.append(lineArr)labelMat.append(float(currLine[1]) * 2 - 1)return mat(self.min_max(dataMat)), labelMatdef sigmoid(self, inx):# return 1.0/(1+exp(min(max(-inx,-10),10)))return 1.0 / (1 + exp(-inx))# 得到对应的特征weight的矩阵def fit(self, data, feature_potential=8, alpha=0.01, iter=100):# alpha是学习速率self.alpha = alphaself.feature_potential = feature_potentialself.iter = iter# dataMatrix用的是mat, classLabels是列表dataMatrix, classLabels = self.loadDataSet(data)print('dataMatrix:',dataMatrix.shape)print('classLabels:',classLabels)k = self.feature_potentialm, n = shape(dataMatrix)# 初始化参数w = zeros((n, 1))  # 其中n是特征的个数w_0 = 0.v = normalvariate(0, 0.2) * ones((n, k))for it in range(self.iter): # 迭代次数# 对每一个样本,优化for x in range(m):# 这边注意一个数学知识:对应点积的地方通常会有sum,对应位置积的地方通常都没有,详细参见矩阵运算规则,本处计算逻辑在:http://blog.csdn.net/google19890102/article/details/45532745# xi·vi,xi与vi的矩阵点积inter_1 = dataMatrix[x] * v# xi与xi的对应位置乘积   与   xi^2与vi^2对应位置的乘积    的点积inter_2 = multiply(dataMatrix[x], dataMatrix[x]) * multiply(v, v)  # multiply对应元素相乘# 完成交叉项,xi*vi*xi*vi - xi^2*vi^2interaction = sum(multiply(inter_1, inter_1) - inter_2) / 2.# 计算预测的输出p = w_0 + dataMatrix[x] * w + interactionprint('classLabels[x]:',classLabels[x])print('预测的输出p:', p)# 计算sigmoid(y*pred_y)-1loss = self.sigmoid(classLabels[x] * p[0, 0]) - 1if loss >= -1:loss_res = '正方向 'else:loss_res = '反方向'# 更新参数w_0 = w_0 - self.alpha * loss * classLabels[x]for i in range(n):if dataMatrix[x, i] != 0:w[i, 0] = w[i, 0] - self.alpha * loss * classLabels[x] * dataMatrix[x, i]for j in range(k):v[i, j] = v[i, j] - self.alpha * loss * classLabels[x] * (dataMatrix[x, i] * inter_1[0, j] - v[i, j] * dataMatrix[x, i] * dataMatrix[x, i])print('the no %s times, the loss arrach %s' % (it, loss_res))self._w_0, self._w, self._v = w_0, w, vdef predict(self, X):if (self._w_0 == None) or (self._w == None).any() or (self._v == None).any():raise NotFittedError("Estimator not fitted, call `fit` first")# 类型检查if isinstance(X, np.ndarray):passelse:try:X = np.array(X)except:raise TypeError("numpy.ndarray required for X")w_0 = self._w_0w = self._wv = self._vm, n = shape(X)result = []for x in range(m):inter_1 = mat(X[x]) * vinter_2 = mat(multiply(X[x], X[x])) * multiply(v, v)  # multiply对应元素相乘# 完成交叉项interaction = sum(multiply(inter_1, inter_1) - inter_2) / 2.p = w_0 + X[x] * w + interaction  # 计算预测的输出pre = self.sigmoid(p[0, 0])result.append(pre)return resultdef getAccuracy(self, data):dataMatrix, classLabels = self.loadDataSet(data)w_0 = self._w_0w = self._wv = self._vm, n = shape(dataMatrix)allItem = 0error = 0result = []for x in range(m):allItem += 1inter_1 = dataMatrix[x] * vinter_2 = multiply(dataMatrix[x], dataMatrix[x]) * multiply(v, v)  # multiply对应元素相乘# 完成交叉项interaction = sum(multiply(inter_1, inter_1) - inter_2) / 2.p = w_0 + dataMatrix[x] * w + interaction  # 计算预测的输出pre = self.sigmoid(p[0, 0])result.append(pre)if pre < 0.5 and classLabels[x] == 1.0:error += 1elif pre >= 0.5 and classLabels[x] == -1.0:error += 1else:continue# print(result)value = 1 - float(error) / allItemreturn valueclass NotFittedError(Exception):"""Exception class to raise if estimator is used before fitting"""passif __name__ == '__main__':fm()

参考连接

  1. https://zhuanlan.zhihu.com/p/3796326
  2. https://www.jianshu.com/p/9a3416ed683b
  3. https://www.cnblogs.com/wkang/p/9588360.html

这篇关于FM、FFM以及DeepFM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/902526

相关文章

DeepFM算法代码

以下代码均采用Tensorflow1.15版本 数据集私聊我 import tensorflow as tfimport numpy as npimport pandas as pd# 定义特征列def get_feature_columns():# 假设 Criteo 数据集有 10 个数值特征和 10 个类别特征numerical_feature_columns = [tf.feat

推荐模型-上下文感知-2015:FFM模型【在FM基础上引入特征域】【每个特征对应的不是唯一一个隐向量权重,而是一系列,与每个特征域都计算出一个隐向量权重】【FM:O(kn);FFM:O(knf)】

Yuchin Juan et al. “Field-aware Factorization Machines for CTR Prediction” in RecSys 2016. https://github.com/rixwew/pytorch-fm 2015年,Criteo基于FM提出的FFM在多项CTR预估大赛中夺魁,并被Criteo、美团等公司深度应用在推荐系统、CTR预估等领域。

爬虫入门--Python利用selenium下载中央广播电台FM广播节目

本文主要利用爬虫技术,来自动下载网页上音频数据 参考资料: 关于python入门,可以学习在imooc网课上搜索Python开发简单爬虫 关于如何加载下一页,参考博客python利用beautifulsoup+selenium自动翻页抓取网页内容 简单爬虫知识  主要分为爬虫调度器,URL管理器,网页下载器,网页解析器,价值数据 爬虫调度器:来开启抓取数据URL管理器:主要来

基于51单片机FM数字收音机设计

基于51单片机FM数字收音机 (程序+原理图+PCB+设计报告) 功能介绍 具体功能: 该系统利主要由STC89C51单片机、液晶显示器、按键、调频收音模块TEA5767、功放LM386组成。 1.收音芯片采用TEA5767模块,采用LM386芯片放大音频功率; 2.LCD1602液晶显示当前所收听的FM频道; 3.可以通过按键进行调换,实现87.5MHz~108MHz调

FM全网自动采集聚合影视搜索源码

源码介绍 FM 全网聚合影视搜索(响应式布局),基于 TP5.1 开发的聚合影视搜索程序,本程序无数据库,本程序内置P2P 版播放器,承诺无广告无捆绑。片源内部滚动广告与本站无关,谨防上当受骗,资源搜索全部来自于网络。 环境要求 PHP>=7.0 服务器 Nginx 安装fileinfo扩展(也就是 thinkPHP 要求的环境) 源码安装方法 直接上传代码到网站运行目录下 配置好

特征交叉系列:FM和深度神经网络的结合,DeepFM原理简述和实践

从FM,FFM到DeepFM 在上两节中介绍了FM和FFM 这两种算法是推荐算法中经典的特征交叉结构,FM将特征交叉分解到底层属性,通过底层属性的点乘来刻画特征交叉的计算,而FFM引入特征域的概念,对不同的特征对所引用的底层属性进行隔离,避免导致多重特征交叉下,底层属性表征产生互相拉扯,导致表达矛盾。 在深度学习时代之前,FM结构是主流的推荐算法,而随着深度学习的到来,FM逐渐和DNN深度神

机器学习笔记——双线性回归 MF、 FM

双线性模型 在推荐系统领域常常使用 含义是二元函数固定一个自变量时,函数关于另外一个自变量是线性的。 矩阵分解模型MF 如果我们需要对一个用户推荐电影我们应该怎么推荐? 结合用户以及用户对电影的评分,可以猜测用户的偏好,如果给某部电影分值很高,这个电影是爱情剧、战争、悬疑、哪个导演、什么时间等等都是特征,将每部电影的特征表示成向量,向量的每一个维度代表应该特征,其值越大就表示电影在某个特征程

Java 22的FFM API,比起Java 21的虚拟线程

哪个对Java未来的发展影响更大?两个 Java 版本中的重要特性:Java 21 的虚拟线程和 Java 22 的 FFM API。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222,私信22,我在后台发给你。 这两个特性都对 Java 的未来发展具有潜在影响,但对不同领域的影响可能会有所不同。虚拟线程:虚拟线程是 Java 21

汽车IVI中控开发入门及进阶(二十一):DAB和FM 收音机

前言: 在过去的十年里,数字收音机对车载娱乐产生了重大影响。现在,几乎每辆新车都标配了这项技术,这也是我们60%以上的人收听收音机的方式。甚至有传言称,在不久的将来,将永久关闭调频发射机,使许多车载收音机过时。但一些相对年轻的汽车在工厂里仍然没有安装DAB,而且为售后市场系统更换整个立体声系统的成本很高,而且可能会失去内置信息娱乐系统的功能。 答案是一个单独的DAB适配器,它连接到汽车现有

比亚迪质量如何用keras实现deepFM

比亚迪质量deepFM 说起来结构还是比较简单,包含了左边的 FM 和右边的 deep 部分,每个神经元进行了什么操作也在图中表示得很清楚。需要注意的是,红线表示权重为 1,黑线表示有需要训练的权重连线。   Addition 普通的线性加权相加,就是 w*x Inner Product 内积操作,就是 FM 的二次项隐向量两两相乘的部分 Sigmoid 激活函数,即最后整合两部分输出合