# 1、FM

## 1.1 背景

### 1.1.1 线性模型

\begin{aligned} f(x) &= \omega_0 + \omega_1x_1+\omega_2x_2+...+\omega_nx_n \\ &=\omega_0+\sum_{i=1}^n{\omega_ix_i} \end{aligned} \qquad (1)

## 1.1.2 二项式模型

$f(x)=\omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n\omega_{ij}x_ix_j \qquad (2)$

$1+n+\frac{n(n-1)}{2}=\frac{1}{2}(n^2+n+2) \qquad (3)$

## 1.2 FM

### 1.2.1 FM基本原理

$V_i = (v_{i1},v_{i2},v_{i3},...,v_{ik})^T\in \mathbb R^k, i=1,2,3,...,n \qquad(4)$

$\omega_{ij}$表示为：
$\omega_{ij}=V_i^TV_j=\sum_{l=1}^kv_{il}v_{jl} \qquad(5)$

$f(x) = \omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n(V_i^TV_j)x_ix_j \qquad(6)$

### 1.2.2 数据分析

$W= \begin{pmatrix} \omega_{11} & \omega_{12}& ... &\omega_{1n} \\ \omega_{21} & \omega_{22}& ... &\omega_{2n} \\ \vdots &\vdots &\ddots &\vdots\\ \omega_{n1} & \omega_{n2}& ... &\omega_{nn} \\ \end{pmatrix}_{n\times n} \qquad(7)$

$V= \begin{pmatrix} v_{11} & v_{12}& ... &v_{1k} \\ v_{21} & v_{22}& ... &v_{2k} \\ \vdots &\vdots &\ddots &\vdots\\ v_{n1} & v_{n2}& ... &v_{nk} \\ \end{pmatrix}_{n\times k}=\begin{pmatrix} V_1^T\\ V_2^T\\ \cdots \\ V_n^T\\ \end{pmatrix} \qquad(8)$

$VV^T = W \qquad(9)$

### 1.2.4 计算时间复杂度

$f(x) = \omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n(V_i^TV_j)x_ix_j \qquad(6)$

\begin{aligned} \sum_{i=1}^{n-1}\sum_{j=i+1}^n(V_i^TV_j)x_ix_j &= \frac{1}{2}\left(\sum_{i=1}^n\sum_{j=1}^n(V_i^TV_j)x_ix_j-\sum_{i=1}^n(V_i^TV_i)x_ix_i\right) \\ &=\frac{1}{2}\left(\sum_{i=1}^n\sum_{j=1}^n\sum_{l=1}^kv_{il}v_{jl}x_ix_j-\sum_{i=1}^n\sum_{l=1}^k v_{il}^2x_i^2\right)\\ &=\frac{1}{2}\sum_{l=1}^k\left(\sum_{i=1}^n(v_{il}x_i)\sum_{j=1}^n(v_{jl}x_j)-\sum_{i=1}^nv_{il}^2x_i^2\right)\\ &=\frac{1}{2}\sum_{l=1}^k\left(\left(\sum_{i=1}^n(v_{il}x_i)\right)^2-\sum_{i=1}^nv_{il}^2x_i^2\right) \end{aligned} \qquad(10)

### 1.2.5 梯度

FM有一个重要的性质：multilinearity：若记$\Theta=(\omega_0,\omega_1,\omega_2,...,\omega_n,v_{11},v_{12},...,v_{nk})$表示FM模型的所有参数，则对于任意的$\theta \in \Theta$，存在与$\theta$无关的$g(x)$$h(x)$，使得式（6）可以表示为：
$f(x) = g(x) + \theta h(x) \qquad(11)$

• $\theta=\omega_0$时，式（6）可以表示为：
$f(x) = \color{blue}{\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n(V_i^TV_j)x_ix_j} +\omega_0 \times \color{red}{1} \qquad(12)$
上述中的蓝色表示$g(x)$，红色表示$h(x)$。下同。
从上述式子可以看出此时的梯度为1.

• $\theta=\omega_l, l \in (1,2,...,n)$时，
$f(x) = \color{blue}{\omega_0+\sum_{i=1,\ i \ne l}^n\omega_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n(V_i^TV_j)x_ix_j}+\omega_l \times \color{red}{x_l} \qquad(13)$
此时梯度为$x_l$

• $\theta=v_{lm}$
$f(x) =\color{blue}{ \omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{i=1}^{n-1}\sum_{j=i+1}^n(\sum_{s=1 , is \ne lm ,js \ne lm}^k v_{is}v_{js})x_ix_j }+v_{lm}\times \color{red}{x_l\sum_{i=1,i \ne l }^n v_{im}x_i} \qquad(14)$
此时梯度为$x_l\sum_{i \ne l } v_{im}x_i$

$\frac{\partial f(x)}{\partial \theta} = \begin{cases} 1, & \theta=\omega_0 \\ x_l, & \theta=\omega_l, l \in (1,2,...,n) \\ x_l\sum_{i=1,i \ne l }^n v_{im}x_i & \theta=v_{lm} \end{cases} \qquad(15)$

### 1.2.6 训练时间复杂度

$x_l\sum_{i=1,i \ne l }^n v_{im}x_i = x_l\sum_{i=1}^n v_{im}x_i-v_{lm}x_l^2 \qquad(16)$

（1）我们首先计算$\sum_{i=1}^n v_{im}x_i$，时间复杂度为n，这个值对于所有特征对应的隐变量的某一个维度是相同的。我们设这值为C。

（2）计算每一个特征对应的$x_l\sum_{i=1}^n v_{im}x_i-v_{lm}x_l^2 =Cx_l-v_{lm}x_l^2$，由于总共有n个特征，因此时间复杂度为n，至此，总的时间复杂度为n+n。

（3）上述只是计算了隐变量的其中一个维度，我们总共有k个维度，因此总的时间复杂度为$k(n+n)=O(kn)$.

# 2、FFM

## 2.2模型与最优化问题

### 2.2.1 模型

$f(x) = \omega_0+\sum_{i=1}^n\omega_ix_i+\sum_{j1=1}^{n-1}\sum_{j2=j1+1}^n(V_{j1,f2}^TV_{j2,f1})x_{j1}x_{j2} \qquad(17)$

$\phi(V,x) = \sum_{j1=1}^{n-1}\sum_{j2=j1+1}^n(V_{j1,f2}^TV_{j2,f1})x_{j1}x_{j2} \qquad(18)$

### 2.2.2 最优化问题

$\min \frac{\lambda}{2}||V||_2^2+\sum_{i=1}^{m}\log(1+exp(-y_i\phi(V,x))) \qquad(19)$

### 2.2.3 自适应学习率

$V_{j1,f2} = V_{j1,f2} - \frac{\eta}{\sqrt{1+\sum_t(g_{v_{j1,f2}}^t)^2}}g_{v_{j1,f2}} \qquad(20)$

### 2.2.4 FFM算法的最终形式

\begin{aligned} (V_{j1,f2})_d &=(V_{j1,f2})_{d-1}-\frac{\eta}{\sqrt{(G_{j1,f2})_d}} \cdot (g_{j1,f2})_d \\ (V_{j2,f1})_d &=(V_{j2,f1})_{d-1}-\frac{\eta}{\sqrt{(G_{j2,f1})_d}} \cdot (g_{j2,f1})_d \end{aligned}

$(G_{j1,f2})_d=(G_{j1,f2})_{d-1}+(g_{j1,f2})_d^2 \\ (G_{j2,f1})_d=(G_{j2,f1})_{d-1}+(g_{j2,f1})_d^2$

g为梯度，比如$g_{j1,f2}$$j1$这个特征对应$f2$这个field的梯度向量：
$g_{ji,f2}=\lambda \cdot V_{ji,f2} + \kappa \cdot V_{j2,f1}\\ g_{j2,f1}=\lambda \cdot V_{j2,f1} + \kappa \cdot V_{j1,f2}$

$\kappa=\frac{\partial\log(1+exp(-y_i\phi(V,x))) }{\partial \phi(V,x) }=\frac{-y}{1+\exp(y\phi(V,x) )}$

## 2.3完整算法流程

### 2.3.1 计算梯度

\begin{aligned} g_{ji,f2}=\lambda \cdot V_{ji,f2} + \kappa \cdot V_{j2,f1} \\ g_{j2,f1}=\lambda \cdot V_{j2,f1} + \kappa \cdot V_{j1,f2} \end{aligned} \qquad(21)

$\kappa=\frac{\partial\log(1+exp(-y_i\phi(V,x))) }{\partial \phi(V,x) }=\frac{-y}{1+\exp(y\phi(V,x) )} \qquad(22)$

（1）在SGD中，式（19）可以转化为：
$\min \frac{\lambda}{2}||V||_2^2+\log(1+exp(-y_i\phi(V,x))) \qquad(23)$
（2）上式对$V_{j1,f2}$求偏导，可得：

\begin{aligned} &\frac{\partial \frac{\lambda}{2}||V||_2^2+\log(1+exp(-y_i\phi(V,x)))}{\partial V_{j1,f2}} \\ &=\lambda \cdot V_{j1,f2} + \frac{\partial \log(1+exp(-y_i\phi(V,x)))}{\partial V_{j1,f2}}\\ &=\lambda \cdot V_{j1,f2} + \frac{\partial \log(1+exp(-y_i\phi(V,x)))}{\partial \phi} \cdot \frac{\partial \phi}{V_{j1,f2}}\\ &=\lambda \cdot V_{j1,f2} + \frac{-y}{1+\exp(y\phi(V,x) )} \cdot V_{j2,f1} \end{aligned} \qquad(24)

### 2.3.2 计算累积梯度平方和

\begin{aligned} (G_{j1,f2})_d=(G_{j1,f2})_{d-1}+(g_{j1,f2})_d^2 \\ (G_{j2,f1})_d=(G_{j2,f1})_{d-1}+(g_{j2,f1})_d^2 \end{aligned} \qquad(26)

### 2.3.3 更新隐变量

\begin{aligned} (V_{j1,f2})_d=(V_{j1,f2})_{d-1}-\frac{\eta}{\sqrt{(G_{j1,f2})_d}} \cdot (g_{j1,f2})_d\\ (V_{j2,f1})_d=(V_{j2,f1})_{d-1}-\frac{\eta}{\sqrt{(G_{j2,f1})_d}} \cdot (g_{j2,f1})_d \end{aligned} \qquad(26)

### 2.3.4 关于初始参数的设定

（1）$\eta$：没有具体的建议，用户根据经验指定即可，一般会取0.1，0.01，0.001。

（2）$V$：在区间$[0,1/\sqrt{k}]$间的随机值，均匀分布即可。

（3）$G$：设置为1，以避免$(G_{j1,f2})_d^{-\frac{1}{2}}$出现很大的值。

## 2.4 时间复杂度

### 2.4.2 训练时间复杂度

$O(kn^2) + 1 + 2k + 2k + 2k = O(kn^2)$

## 2.5 计算速度优化

### 2.5.1 openMP

OpenMP提供的这种对于并行描述的高层抽象降低了并行编程的难度和复杂度，这样程序员可以把更多的精力投入到并行算法本身，而非其具体实现细节。对基于数据分集的多线程程序设计，OpenMP是一个很好的选择。同时，使用OpenMP也提供了更强的灵活性，可以较容易的适应不同的并行系统配置。线程粒度和负载平衡等是传统多线程程序设计中的难题，但在OpenMP中，OpenMP库从程序员手中接管了部分这两方面的工作。

openPM原生支持C/C++/Fortran，但java可以通过jomp等引入，未测试。

### 2.5.2 SSE3

。SSE3 中13个新指令的主要目的是改进线程同步和特定应用程序领域，例如媒体和游戏。这些新增指令强化了处理器在浮点转换至整数、复杂算法、视频编码、SIMD浮点寄存器操作以及线程同步等五个方面的表现，最终达到提升多媒体和游戏性能的目的。Intel是从Prescott核心的Pentium 4开始支持SSE3指令集的，而AMD则是从2005年下半年Troy核心的Opteron开始才支持SSE3的。但是需要注意的是，AMD所支持的SSE3与Intel的SSE3并不完全相同，主要是删除了针对Intel超线程技术优化的部分指令。
SSE3指令采用128位的寄存器，可以同时操作4个单精度浮点数或者整数，因此非常类似于向量运算。这对于有大量向量计算的的FFM模型是有用的。

### 2.5.3 ParameterServer

https://www.zybuluo.com/Dounm/note/517675
Paraeter Server框架中，每个server都只负责分到的部分参数（server共同维持一个全局共享参数）。server节点可以和其他server节点通信，每个server负责自己分到的参数，server group共同维持所有参数的更新。server manage node负责维护一些元数据的一致性，例如各个节点的状态，参数的分配情况。

## 2.6模型优化

### 2.6.1 特征编码连续

（1）使用hashmap，而非数组。
（2）将有意义的编码映射到一个连续的编码空间。

### 2.6.3 样本归一化

$R[i]=\frac{1}{||X||}$

### 2.6.4 特征归一化

04-29 4382

11-13 1万+

01-07

08-03 3万+

08-07 5万+

03-09 3346

07-13 2833

03-26 4万+

12-29 6万+

08-24 4183

11-22 8802

09-26

09-01 4812

03-22 4万+

03-17 2977

04-30 3万+

04-20 299

03-16 10万+

07-10 166

05-24 276

01-04 5593

02-26 8万+

03-05 9321

09-13 92

02-22 7955

03-27 886

04-25 6万+

03-10 2万+

09-01 3593

06-25 732

05-01 1万+

03-31 88

05-07 9460

07-30 409

02-11 1万+

06-09 557

02-15 18万+

12-25 1100

02-17 8708

07-19 951

03-20 3万+

03-04 14万+

02-03 18万+

07-29 1327

08-09 692

03-19 3万+

06-12 95

04-12 109

03-12 11万+

06-08 2132

10-30 969

03-08 7万+

07-01 604

03-18 9308

12-19 7455

04-06 7万+

01-26 1万+

03-18 4万+

06-06 1万+

03-10 18万+

03-30 16万+

03-15 7万+

03-18 8720

08-29 105

03-22 2万+

01-21 28万+

02-06 19万+

03-11 2万+

03-19 6万+

02-15 1万+

03-26 3万+

05-06 3万+

03-23 4万+

02-11 12万+

02-06 6万+

04-03 1万+

08-20 2万+

04-04 116

#### fm ffm模型

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客