大规模分段线性模型(LS-PLM)及其在推荐系统中作用

72 阅读6分钟

实验和完整代码

完整代码实现和jupyter运行:github.com/Myolive-Lin…

引言

点击通过率(CTR) 预测是推荐系统行业的一个核心问题Gai et al. (2017)提到:为了提高CTR预测的准确性,越来越多的数据被涉及,使得CTR预测成为一个大规模学习问题,具有大量的样本和高维特征。传统的解决方案是应用线性逻辑回归(LR)模型,并以并行方式训练。然而,CTR预测问题是一个高度非线性问题,用户点击生成涉及许多复杂因素,如广告质量、上下文信息、用户兴趣以及这些因素之间的复杂交互。为了帮助LR模型捕捉非线性,探索了特征工程技术,但这既耗时又耗人力。另一个方向是使用设计良好的模型来捕捉非线性。Facebook使用了一种混合模型,将决策树与逻辑回归相结合。然而,基于树的方法不适合非常稀疏和高维的数据。Rendle引入了因子分解机(FM),使用二阶函数(或使用其他给定数量阶函数)涉及特征之间的交互。然而,FM不能拟合数据中所有一般非线性模式(如其他高阶模式)


2 LS-PLM模型

注意理论方法由Gai et al. (2017)等人提出,感兴趣可以去查找一下原文。

将大规模点击率预测视为数据集 {xt,yt}t=1n\{x_t, y_t\}_{t=1}^n 的二元分类问题,其中 yt{0,1}y_t \in \{0,1\}xtRdx_t \in \mathbb{R}^d 是高维且稀疏的。

2.1 Formulation

为了对非线性建模,我们采用分而治之的策略:

p(y=1x)=g(j=1mσ(ujTx)η(wjTx))(1)p(y=1|x) = g\left(\sum_{j=1}^m \sigma(u_j^T x)\eta(w_j^T x)\right) \tag{1}

Parameters:

Θ={u1,,um,w1,,wm}Rd×2m\Theta = \{u_1,\cdots,u_m, w_1,\cdots,w_m\} \in \mathbb{R}^{d\times 2m}
  • {uj}\{u_j\}σ()\sigma(\cdot) 的分区参数
  • {wj}\{w_j\}η()\eta(\cdot)的预测参数

Special Case (Softmax + Sigmoid):
g(x)=xg(x)=xσ(x)=softmax\sigma(x)=\text{softmax}η(x)=sigmoid\eta(x)=\text{sigmoid}时:

p(y=1x)=i=1mexp(uiTx)j=1mexp(ujTx)11+exp(wiTx)(2)p(y=1|x) = \sum_{i=1}^m \frac{\exp(u_i^T x)}{\sum_{j=1}^m \exp(u_j^T x)} \cdot \frac{1}{1+\exp(-w_i^T x)} \tag{2}

相当于混合模型:

p(y=1x)=i=1mp(z=ix)Partitionp(yz=i,x)Prediction(3)p(y=1|x) = \sum_{i=1}^m \underbrace{p(z=i|x)}_{\text{Partition}} \underbrace{p(y|z=i,x)}_{\text{Prediction}} \tag{3}

目标函数

argminΘf(Θ)=loss(Θ)+λΘ2,1+βΘ1(4)\arg\min_\Theta f(\Theta) = \text{loss}(\Theta) + \lambda\|\Theta\|_{2,1} + \beta\|\Theta\|_1 \tag{4}

损失函数

loss(Θ)=t=1n[ytlogp(yt=1xt,Θ)+(1yt)logp(yt=0xt,Θ)](5)\text{loss}(\Theta) = -\sum_{t=1}^n \left[ y_t \log p(y_t=1|x_t,\Theta) + (1-y_t)\log p(y_t=0|x_t,\Theta) \right] \tag{5}

Regularizations:

  1. L2,1L_{2,1}范数(特征选择):
Θ2,1=i=1dj=12mθij2\|\Theta\|_{2,1} = \sum_{i=1}^d \sqrt{\sum_{j=1}^{2m} \theta_{ij}^2}
  1. L1L_1 范数(稀疏性):
Θ1=i,jθij\|\Theta\|_1 = \sum_{i,j} |\theta_{ij}|

Key Properties

  1. 由于 L1L_1/L2,1L_{2,1} 项导致的非凸和非平滑目标
  2. 显式稀疏控制:
    • 特征选择(抑制不重要的特征)
    • 模型可解释性
    • 存储和预测的高效性

Notations

符号描述
mm分区数量
σ()\sigma(\cdot)配分函数(例如,softmax)
η()\eta(\cdot)预测函数(例如 sigmoid)
λ,β\lambda,\beta正则化系数

2.1 LS-PLM模型优势

LS-PLM遵循分而治之的策略,即首先将特征空间划分为几个局部区域,然后在每个区域中拟合一个线性模型,结果是加权线性预测的组合。这两个步骤是同时以监督方式学习的,旨在最小化预测损失。LS-PLM在三个方面优于传统的LR模型:

  • 非线性:只要有足够的划分区域,LS-PLM可以拟合任何复杂的非线性函数。
  • 可扩展性:与LR模型类似,LS-PLM可以扩展到大量的样本和高维特征。我们设计了一个分布式系统,可以在数百台机器上并行训练模型。在我们的在线产品系统中,每天都会训练和部署数十个具有数千万参数的LS-PLM模型。
  • 稀疏性:正如Brendan等人在2013年指出的,模型稀疏性是工业环境中在线服务的一个实际问题。Gai et al. (2017)展示了带有L1和L2,1正则化的LS-PLM可以实现良好的稀疏性,使模型的部署更加轻量级。模型服务过程仅需使用权重非零特征,因此稀疏模型也能使其在线推断的效率更高。

对于非线性可以从下图得知: 图 A 是演示数据集。这是一个二分类问题,红点属于正类,蓝点属于负类。图B所示使用LR模型的分类结果。图C显示了使用LS-PLM模型的分类结果。可以看出来明确LS-PLM可以捕获数据的非线性分布。

image.png

LS-PLM与深度学习模型对比

LS-PLM其实可以是看作三层的神经网络,其模型如下

image.png

2.3 torch实现

模型定义

class LS_PLM(nn.Module):
    """
    基于LS-PLM的分类模型
    """
    def __init__(self, num_features, num_classes):
        super(LS_PLM, self).__init__()
        # 聚类模型,采用softmax输出类别概率
        self.num_classes = num_classes
        self.cluster_fc = nn.Sequential(
            nn.Linear(num_features, num_classes).float(),
            nn.Softmax(dim=1)
        )
        
        self.lr_fc = nn.Sequential(
            nn.Linear(num_features, self.num_classes, bias= True).float(),
            nn.Sigmoid()
        )

    def forward(self, x):
        """
        前向传播函数
        :param x: 输入数据
        :return: 模型输出
        """
        softmax_output = self.cluster_fc(x)
        lr_output = self.lr_fc(x)
        output = torch.sum(softmax_output * lr_output, dim=1, keepdim= True) #与输入维度保持一致
        return output
    
    def get_regularization(self, l1=0., l21=0.):
        """
        计算L1和L2,1正则项
        :param l1: L1正则系数
        :param l21: L2,1正则系数
        :return: 正则损失项
        """
        reg_loss = 0
        
        for name, param in self.named_parameters():
            if 'weight' in name:
                # L2,1正则项 (按行计算L2范数后求和)
                if l21 > 0:
                    row_norms = torch.norm(param, p=2, dim=1)  # 计算每行的L2范数
                    reg_loss += l21 * torch.sum(row_norms)     # 对行范数求和
                    
                # L1正则项
                if l1 > 0:
                    reg_loss += l1 * torch.sum(torch.abs(param))
                    
        return reg_loss

            

模型参数

# 参数设置
epoch = 100
lr = 0.005
num_classes = 12
batch_size = 32
l1_lambda = 1e-4
l2_1lambda = 1e-5

# 模型构建
model = LS_PLM(X.shape[1], num_classes=num_classes)
optimizer = optim.Adam(model.parameters(), lr=lr)  
criterion = nn.BCELoss(reduction='mean')

模型训练

# 模型训练
loss_history = []
validation_loss_history = []
Auc_history = []
validation_Auc_history = []

pbar = tqdm(range(epoch), desc='Training')

for i in pbar:
    model.train()
    # 前向传播
    y_pred = model(X_train)
    loss = criterion(y_pred.squeeze(), y_train)
    
    #添加正则化
    reg_loss = model.get_regularization(l1 = l1_lambda, l21 = l2_1lambda)
    total_loss = loss + reg_loss

    # 反向传播
    optimizer.zero_grad()
    total_loss.backward()
    optimizer.step()
    
    loss_history.append(total_loss.item())
    Auc_history.append(roc_auc_score(y_train.detach().numpy(), (y_pred).detach().numpy()))

    model.eval()
    with torch.no_grad():
        y_pred = model(X_validation)
        validation_loss = criterion(y_pred.squeeze(), y_validation)
        validaiton_reg_loss = model.get_regularization(l1_lambda,l2_1lambda)
        total_validation_loss = validation_loss + validaiton_reg_loss

        validation_loss_history.append(total_validation_loss.item())
        validation_Auc_history.append(roc_auc_score(y_validation.detach().numpy(), (y_pred).detach().numpy()))

    pbar.set_postfix({'validation_Loss': f'{total_validation_loss.item():.4f}',
                      'train_loss':f'{total_loss.item():.4f}'})

2.4模型评估

通过训练,我们观察到模型的训练损失和验证损失逐步减少,证明了模型在训练过程中逐渐收敛,并且能够有效地拟合训练数据。在训练后期,模型的auc值始终大于0.9,表明模型的预测效果较好

image.png AUC(ROC曲线下的面积)

AUC是衡量二分类模型性能的重要指标。在本实验中,模型的训练集和验证集上的AUC值持续上升,并在最终达到了较高的值,证明LS-PLM能够有效地进行CTR预测。通过绘制ROC曲线,我们可以直观地看到模型在正负样本上的区分能力。

最终的ROC曲线如下所示:

image.png

预测结果可视化

模型的预测结果可视化表明,LS-PLM在识别点击广告的概率时,能够较为准确地估计用户行为。以下是部分预测结果与实际标签的对比:

预测实际标签
0.9118211.0
0.6395501.0
0.9506041.0
0.2925600.0
0.9671431.0
......
0.0471140.0
0.0155660.0
0.9469311.0
0.2979110.0
0.0351240.0

总结

  • LS-PLM在CTR预测中表现良好:通过使用LS-PLM,我们能够有效地捕捉到数据中的非线性关系,进而提高CTR预测的准确性。
  • 正则化和稀疏性控制:通过L1和L21正则化的应用,模型能够有效控制过拟合,并实现良好的稀疏性,使模型的部署更加轻量级。模型服务过程仅需使用权重非零特征,因此稀疏模型也能使其在线推断的效率更高,并提升泛化能力。

Reference

1、Gai, K., Zhu, X., Li, H., Liu, K., & Wang, Z. (2017). Learning piece-wise linear models from large scale data for ad click prediction. arXiv preprint arXiv:1704.05194.

2、王喆 《深度学习推荐系统》
3、经典推荐算法学习(四)| 阿里LS-PLM(MLR)模型原理解析