前言

FTRL(Follow the Regularized Leader)是一种专为在线学习场景设计的优化算法,尤其适用于高维稀疏数据(如推荐系统、广告点击率预测)。其核心目标是通过动态调整学习率和正则化项,在保证模型精度的同时提升参数稀疏性。下面介绍下FTRL的核心原理和相关应用详解。

算法原理与核心公式

  1. 基础框架FTRL结合了FOBOS(前向后向切分)RDA(正则对偶平均)的优点,其更新公式为:

其中: • $g_s$为第$s$轮的梯度; • $\sigma_s$为自适应的学习率系数; • $\lambda_1$和$\lambda_2$分别控制L1和L2正则化强度。

  1. 稀疏性机制通过L1正则项($\lambda_1 |w|_1$)强制不重要的特征权重归零。当梯度的累积值小于$\lambda_1$时,权重直接置零,从而实现稀疏性。

  2. 自适应学习率 采用Per-Coordinate Learning Rate,每个特征有独立的学习率:

其中$\alpha$和$\beta$为超参数,高频更新的特征学习率更低,低频特征学习率更高。

与SGD对比

  1. 高稀疏性相比传统SGD,FTRL在在线学习中能更有效地剔除冗余特征,减少模型存储和计算开销。
  2. 稳定性与低Regret通过正则化项限制参数更新幅度,避免因单样本噪声导致的剧烈波动,从而降低累积遗憾(Regret)。
  3. 适应流式数据 支持单样本或小批量更新,适合实时处理大规模数据流,如广告点击日志。

超参数调优

在TensorFlow等框架中,FTRL的关键参数包括: • 学习率相关:$\alpha$(初始学习率)、$\beta$(平滑项,防止除零); • 正则化项:$\lambda_1$(L1强度,控制稀疏性)、$\lambda_2$(L2强度,防止过拟合); • 衰减策略:可结合学习率衰减(如指数衰减)进一步提升收敛性。

示例代码(TensorFlow):

optimizer = tf.train.FtrlOptimizer(
    learning_rate=0.1,
    learning_rate_power=-0.5,
    l1_regularization_strength=0.01,
    l2_regularization_strength=0.1
)

应用场景

  1. 推荐系统:处理用户行为日志等高维稀疏特征,实时更新模型;
  2. 广告点击率预测:快速适应广告位和用户兴趣的动态变化;
  3. 自然语言处理:对文本特征进行稀疏编码,提升推理效率。

局限性

计算复杂度:Per-Coordinate设计增加了内存和计算开销,需权衡性能与效果; • 超参数敏感:$\lambda_1$和$\alpha$的调整对结果影响显著,需通过交叉验证优化。

FTRL工程实现

avatar

per-coordinate

per-coordinate指FTRL是对w每一维分开训练更新的,每一维使用的是不同的学习速率,也是上面代码中lamda2之前的那一项。与w所有特征维度使用统一的学习速率相比,这种方法考虑了训练样本本身在不同特征上分布的不均匀性,如果包含w某一个维度特征的训练样本很少,每一个样本都很珍贵,那么该特征维度对应的训练速率可以独自保持比较大的值,每来一个包含该特征的样本,就可以在该样本的梯度上前进一大步,而不需要与其他特征维度的前进步调强行保持一致。

参数建议

在使用Per-coordinate FTRL-Proximal算法进行逻辑回归时,选择合适的超参数(α、β、λ1、λ2)是至关重要的,因为这些参数会直接影响模型的收敛性和性能。以下是一些关于这些参数的建议和调整思路:

1. α(学习率)

  • 建议取值范围:通常选择一个较小的正值,比如0.01、0.1等。
  • 调整方法:可以使用交叉验证来选择最优学习率,或者尝试逐步减小学习率,观察模型性能的变化。

2. β(Momentum参数)

  • 建议取值范围:常取值在0.5到0.9之间,不同情况下可能需要调整。
  • 调整方法:较大的β(如0.9)通常能加速收敛,但也可能引入不稳定性。可以尝试不同的值,找出最佳的平衡点。

3. λ1(L1正则化参数)

  • 建议取值范围:这个值通常取较小的数值,比如0.001、0.01等。
  • 调整方法:L1正则化可以选择性地将一部分特征权重置为零,有助于特征选择。可以使用网格搜索等方法尝试不同的λ1值,以观察对最终模型的影响。

4. λ2(L2正则化参数)

  • 建议取值范围:与λ1相似,通常也取较小的值,例如0.001、0.01等。
  • 调整方法:L2正则化有助于防止模型过拟合。可以与λ1结合测试,观察其对模型复杂性的影响。

调整超参数的建议步骤

  1. 固定参数网格搜索:选择一些值进行网格搜索,同时固定其他参数,观察不同组合作用下的模型性能(如准确率、F1分数等)。
  2. 交叉验证:使用交叉验证评估不同超参数组合的表现,选择表现最佳的组合。
  3. 学习率调度:在训练的过程中,可以使用学习率衰减策略,动态调整学习率以提高收敛速度。

实际应用的考虑

在实践中,建议从较小的参数值开始,逐步进行实验,结合模型的训练和验证损失来调整这些参数。希望这些建议能帮助你选择到合适的超参数,如果有更多特定的上下文或数据集信息,我可以提供更精确的建议!

后记

今天(17年8月)参照着上述公式,自己实现了spark版本的ftrl,后续弄成参数服务器版本的。

调用接口

以下代码为旧版本,新版本增加了treeAggregate:

var count = 0
// 注意要collect,否则有问题,血的教训
dataTrain.collect.foreach{ case lp: LabeledPoint =>
  ftrlModel.update(lp.features.toSparse, lp.label.toInt)
  count += 1
  if (count % 100 == 0) {
    saveMetric(sparkContext, dataTest, ftrlModel.ws, modelMetricPath + "/" + count.toString, count.toString)
  }
}

参考