FM到FFM——自动特征交叉

FM到FFM——自动特征交叉

概述

在推荐系统中,特征交叉是一种常见的特征工程手段,它可以帮助模型捕捉特征之间的相互作用关系。然而,手动进行特征交叉可能会导致特征维度的爆炸,同时也无法保证交叉特征的有效性。因此,自动特征交叉的方法应运而生,其中最具代表性的算法是因子分解机(Factorization Machines, FM)和场感知因子分解机(Field-aware Factorization Machines, FFM)。

[关键词:因子分解机、场感知因子分解机、特征交叉、推荐系统、数学推导、Python实现]

目录

因子分解机(FM)

FM原理

因子分解机(FM)是一种能够自动进行特征交叉的模型,它通过引入隐向量的方式,实现了特征之间的二阶交叉。FM模型的数学表达式为:

y ^ ( x ) = w 0 + ∑ i = 1 n w i x i + ∑ i = 1 n ∑ j = i + 1 n ⟨ v i , v j ⟩ x i x j \hat{y}(x) = w_0 + \sum_{i=1}^{n}w_ix_i + \sum_{i=1}^{n}\sum_{j=i+1}^{n}\langle v_i, v_j \rangle x_ix_j y^(x)=w0+i=1nwixi+i=1nj=i+1nvi,vjxixj

其中,(w_0)是全局偏置项,(w_i)是第(i)个特征的权重,(v_i)是第(i)个特征的隐向量,(\langle v_i, v_j \rangle)表示隐向量的内积,(x_i)和(x_j)是输入特征向量中的第(i)个和第(j)个特征值。

数学推导

FM模型的损失函数通常采用平方损失函数,其数学表达式为:

L ( y , y ^ ) = 1 2 ( y − y ^ ) 2 L(y, \hat{y}) = \frac{1}{2}(y - \hat{y})^2 L(y,y^)=21(yy^)2

为了优化损失函数,我们采用梯度下降算法进行迭代更新。对于

样本(i),损失函数关于权重(w_i)、隐向量(v_i)和全局偏置项(w_0)的梯度分别为:

∂ L ∂ w i = − ( y − y ^ ) x i \frac{\partial L}{\partial w_i} = -(y - \hat{y})x_i wiL=(yy^)xi

∂ L ∂ v i = − ( y − y ^ ) x i ( ∑ j = 1 n v j x j − v i x i ) \frac{\partial L}{\partial v_i} = -(y - \hat{y})x_i\left(\sum_{j=1}^{n}v_jx_j - v_ix_i\right) viL=(yy^)xi(j=1nvjxjvixi)

∂ L ∂ w 0 = − ( y − y ^ ) \frac{\partial L}{\partial w_0} = -(y - \hat{y}) w0L=(yy^)

其中,(y)表示真实标签,(\hat{y})表示预测值。

根据梯度下降的原理,我们可以对权重(w_i)、隐向量(v_i)和全局偏置项(w_0)进行迭代更新:

w i ← w i − α ∂ L ∂ w i w_i \leftarrow w_i - \alpha \frac{\partial L}{\partial w_i} wiwiαwiL

v i ← v i − α ∂ L ∂ v i v_i \leftarrow v_i - \alpha \frac{\partial L}{\partial v_i} viviαviL

w 0 ← w 0 − α ∂ L ∂ w 0 w_0 \leftarrow w_0 - \alpha \frac{\partial L}{\partial w_0} w0w0αw0L

其中,(\alpha)是学习率,用于控制参数更新的步长。

Python实现

接下来,我们使用Python实现FM模型,并通过注释解释代码的每个部分。

import numpy as np

class FM:
    def __init__(self, n_features, n_factors, lr, epochs):
        self.n_features = n_features
        self.n_factors = n_factors
        self.lr = lr
        self.epochs = epochs
        self.w0 = 0
        self.w = np.zeros(n_features)
        self.v = np.random.normal(0, 0.1, (n_features, n_factors))
        
    def predict(self, X):
        linear_terms = np.dot(X, self.w)
        interactions = 0.5 * np.sum(np.dot(X, self.v) ** 2 - np.dot(X ** 2, self.v ** 2), axis=1)
        return self.w0 + linear_terms + interactions
    
    def fit(self, X, y):
        for epoch in range(self.epochs):
            y_hat = self.predict(X)
            loss = 0.5 * np.mean((y - y_hat) ** 2)
            print("Epoch: {}, Loss: {:.4f}".format(epoch + 1, loss))
            
            # 更新参数
            self.w0 -= self.lr * np.mean(y_hat - y)
            self.w -= self.lr * np.dot(y_hat - y, X)
            for i in range(self.n_features):
                for f in range(self.n_factors):
                    self.v[i, f] -= self.lr * np.mean((y_hat - y) * X[:, i] * (np.dot(X, self.v[:, f]) - self.v[i, f] * X[:, i]))

场感知因子分解机(FFM)

FFM原理

场感知因子分解机(FFM)是FM模型的扩展,它引入了“场”的概念,使得模型能够区分不同场的特征交叉。在FFM模型

中,每个特征都会有多个隐向量,每个隐向量对应一个场。FFM模型的数学表达式为:

y ^ ( x ) = w 0 + ∑ i = 1 n w i x i + ∑ i = 1 n ∑ j = i + 1 n ⟨ v i , f j , v j , f i ⟩ x i x j \hat{y}(x) = w_0 + \sum_{i=1}^{n}w_ix_i + \sum_{i=1}^{n}\sum_{j=i+1}^{n}\langle v_{i,f_j}, v_{j,f_i} \rangle x_ix_j y^(x)=w0+i=1nwixi+i=1nj=i+1nvi,fj,vj,fixixj

其中,(w_0)是全局偏置项,(w_i)是第(i)个特征的权重,(v_{i,f_j})是第(i)个特征在第(j)个特征场的隐向量,(\langle v_{i,f_j}, v_{j,f_i} \rangle)表示隐向量的内积,(x_i)和(x_j)是输入特征向量中的第(i)个和第(j)个特征值,(f_i)和(f_j)分别表示第(i)个特征和第(j)个特征所属的场。

数学推导

FFM模型的损失函数与FM模型相同,通常采用平方损失函数。对于样本(i),损失函数关于权重(w_i)、隐向量(v_{i,f_j})和全局偏置项(w_0)的梯度分别为:

∂ L ∂ w i = − ( y − y ^ ) x i \frac{\partial L}{\partial w_i} = -(y - \hat{y})x_i wiL=(yy^)xi

∂ L ∂ v i , f j = − ( y − y ^ ) x i ( ∑ j = 1 n v j , f i x j − v i , f j x i ) \frac{\partial L}{\partial v_{i,f_j}} = -(y - \hat{y})x_i\left(\sum_{j=1}^{n}v_{j,f_i}x_j - v_{i,f_j}x_i\right) vi,fjL=(yy^)xi(j=1nvj,fixjvi,fjxi)

∂ L ∂ w 0 = − ( y − y ^ ) \frac{\partial L}{\partial w_0} = -(y - \hat{y}) w0L=(yy^)

其中,(y)表示真实标签,(\hat{y})表示预测值。

根据梯度下降的原理,我们可以对权重(w_i)、隐向量(v_{i,f_j})和全局偏置项(w_0)进行迭代更新:

w i ← w i − α ∂ L ∂ w i w_i \leftarrow w_i - \alpha \frac{\partial L}{\partial w_i} wiwiαwiL

v i , f j ← v i , f j − α ∂ L ∂ v i , f j v_{i,f_j} \leftarrow v_{i,f_j} - \alpha \frac{\partial L}{\partial v_{i,f_j}} vi,fjvi,fjαvi,fjL

w 0 ← w 0 − α ∂ L ∂ w 0 w_0 \leftarrow w_0 - \alpha \frac{\partial L}{\partial w_0} w0w0αw0L

其中,(\alpha)是学习率,用于控制参数更新的步长。

Python实现

接下来,我们使用Python实现FFM模型,并通过注释解释代码的每个部分。

import numpy as np

class FFM:
    def __init__(self, n_features, n_fields, n_factors, lr, epochs):
        self.n_features = n_features
        self.n_fields = n_fields
        self.n_factors = n_factors
        self.lr = lr
        self.epochs = epochs
        self.w0 =

0
        self.w = np.zeros(n_features)
        self.v = np.random.normal(0, 0.1, (n_features, n_fields, n_factors))
        
    def predict(self, X):
        linear_terms = np.dot(X, self.w)
        interactions = 0
        for i in range(self.n_features):
            for j in range(i + 1, self.n_features):
                field_i = self.field_indices[i]
                field_j = self.field_indices[j]
                interactions += np.dot(self.v[i, field_j], self.v[j, field_i]) * X[:, i] * X[:, j]
        interactions = 0.5 * interactions
        return self.w0 + linear_terms + interactions
    
    def fit(self, X, y, field_indices):
        self.field_indices = field_indices
        for epoch in range(self.epochs):
            y_hat = self.predict(X)
            loss = 0.5 * np.mean((y - y_hat) ** 2)
            print("Epoch: {}, Loss: {:.4f}".format(epoch + 1, loss))
            
            # 更新参数
            self.w0 -= self.lr * np.mean(y_hat - y)
            self.w -= self.lr * np.dot(y_hat - y, X)
            for i in range(self.n_features):
                for f in range(self.n_fields):
                    for k in range(self.n_factors):
                        field_i = self.field_indices[i]
                        self.v[i, f, k] -= self.lr * np.mean((y_hat - y) * X[:, i] * (np.dot(X[:, field_i], self.v[:, f, k]) - self.v[i, f, k] * X[:, i]))

总结

本文详细介绍了因子分解机(FM)和场感知因子分解机(FFM)的原理、数学推导以及Python实现。FM和FFM是推荐系统中常用的自动特征交叉模型,能够有效捕捉特征之间的相互作用关系,从而提升模型的预测性能。

FM模型通过引入隐向量实现了特征之间的二阶交叉,而FFM模型在FM的基础上引入了“场”的概念,使得模型能够区分不同场的特征交叉。这两种模型在推荐系统、点击率预估等任务中都有广泛的应用。

需要注意的是,虽然FM和FFM能够自动进行特征交叉,但它们仅考虑了特征之间的二阶交叉关系,对于更高阶的特征交叉可能无法很好地建模。此外,随着特征数量和场的数量的增加,FFM模型的参数量会显著增加,可能导致计算复杂度较高。

参考文献

  1. Rendle, S. (2010). Factorization machines. In Proceedings of the 10th IEEE International Conference on Data Mining (ICDM), pp. 995-1000.
  2. Juan, Y., Zhuang, W., Chin, W. S., & Lin, C. J. (2016). Field-aware factorization machines for CTR prediction. In Proceedings of the 10th ACM Conference on Recommender Systems (RecSys), pp. 43-50.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值