搜广推校招面经五十八

小红书推荐算法

一、BN(Batch Normalization)在训练和测试的区别

Batch Normalization(批归一化,BN)是一种加速深度神经网络训练的技术,它通过对每个 mini-batch 计算均值和方差来归一化输入特征,从而稳定训练过程,减少梯度消失/梯度爆炸问题。

1.1. 训练阶段

在训练过程中,BN 采用 mini-batch 统计信息 进行归一化:

  • 计算方式
    • 计算当前 mini-batch 的均值和方差:
      μ B = 1 m ∑ i = 1 m x i \mu_B = \frac{1}{m} \sum_{i=1}^{m} x_i μB=m1i=1∑mxi
      σ B 2 = 1 m ∑ i = 1 m ( x i − μ B ) 2 \sigma_B^2 = \frac{1}{m} \sum_{i=1}^{m} (x_i - \mu_B)^2 σB2=m1i=1∑m(xi−μB)2
    • 归一化:
      x ^ i = x i − μ B σ B 2 + ϵ \hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} x^i=σB2+ϵ xi−μB
    • 进行缩放和平移:
      y i = γ x ^ i + β y_i = \gamma \hat{x}_i + \beta yi=γx^i+β
  • 关键点
    • 训练时,每个 batch 都会 单独计算均值和方差
    • 由于 mini-batch 之间的统计信息不同,BN 计算的均值和方差会有波动。
    • 为了测试时稳定 ,BN 维护一个 全局均值和方差 ,通过滑动平均 的方式更新:
      μ global ← ( 1 − α ) ⋅ μ global + α ⋅ μ B \mu_{\text{global}} \leftarrow (1 - \alpha) \cdot \mu_{\text{global}} + \alpha \cdot \mu_B μglobal←(1−α)⋅μglobal+α⋅μB
      σ global 2 ← ( 1 − α ) ⋅ σ global 2 + α ⋅ σ B 2 \sigma^2_{\text{global}} \leftarrow (1 - \alpha) \cdot \sigma^2_{\text{global}} + \alpha \cdot \sigma^2_B σglobal2←(1−α)⋅σglobal2+α⋅σB2
    • 其中 α \alpha α 是动量系数(通常设为 0.9 或 0.99)。

1.2. 测试阶段

在测试阶段,BN 不再依赖 mini-batch 统计,而是使用 训练过程中累积的全局均值和方差

  • 计算方式
    • 使用全局均值和方差:
      x ^ i = x i − μ global σ global 2 + ϵ \hat{x}i = \frac{x_i - \mu{\text{global}}}{\sqrt{\sigma^2_{\text{global}} + \epsilon}} x^i=σglobal2+ϵ xi−μglobal
    • 进行缩放和平移:
      y i = γ x ^ i + β y_i = \gamma \hat{x}_i + \beta yi=γx^i+β
  • 关键点
    • 不再计算 batch 统计量 ,而是使用训练时累积的全局均值和方差
    • 这样可以保证测试阶段的稳定性,避免 batch 之间的分布变化导致不一致性。

1.3. 训练和测试的关键区别

训练阶段 测试阶段
归一化方式 用当前 mini-batch 的均值和方差 用全局均值和方差
统计信息计算 每个 batch 单独计算 直接使用训练时累积的全局均值和方差
统计信息是否更新 通过滑动平均更新全局均值和方差 不更新(固定全局均值和方差)
计算公式 μ B , σ B 2 \mu_B, \sigma_B^2 μB,σB2 来归一化 μ global , σ global 2 \mu_{\text{global}}, \sigma^2_{\text{global}} μglobal,σglobal2 来归一化
适用场景 训练时,batch 统计可能波动 测试时,保证稳定性

1.4. BN 训练和测试不一致的问题

(1) 训练和测试分布不匹配

  • 在训练时,每个 mini-batch 计算的均值和方差会有一定波动,而测试时使用的是固定的全局均值和方差。
  • 这可能导致训练和测试阶段的特征分布不同,影响模型性能。

(2) BN 在小 batch size 下的影响

  • 若 batch size 很小(例如 m = 2 m=2 m=2 或 m = 4 m=4 m=4),计算的均值和方差可能波动较大,导致 BN 训练时不稳定。
  • 解决方法:
    • 使用 Group Normalization(GN):在通道维度上进行归一化,避免 batch size 过小的问题。
    • 调整 BN 的 momentum 参数 :降低 α \alpha α,让全局均值和方差更稳定。

二、Dropout在训练和测试的区别

见【搜广推校招面经二十七

三、ID 类特征如何处理、连续值分桶的原因?

推荐系统中,用户 ID、物品 ID、类别 ID 等 ID 类特征 不能直接用于模型,需要进行特征工程。

(1) One-Hot 编码

  • 方法:为每个 ID 创建一个独立的维度,属于该 ID 的样本对应位置设为 1,其他为 0。
  • 缺点
    • 维度极高,存储和计算成本大(如百万级别 ID)。
    • 过于稀疏,无法挖掘 ID 之间的相似性。
  • 适用场景:类别较少时可用,如少量离散标签。

(2) Embedding 向量化

  • 方法
    • 通过 Embedding 层 将 ID 映射为低维稠密向量。
    • Embedding 维度通常为 log(n) ~ sqrt(n)(n 为 ID 种类数)。
    • 训练过程中,Embedding 通过梯度更新,学习 ID 之间的相似性。
  • 优点
    • 解决高维稀疏问题,降低计算复杂度。
    • 允许 ID 之间的特征共享,提高泛化能力。
  • 适用场景:用户 ID、商品 ID、类别 ID、品牌等离散特征。

(3) 统计特征(Target Encoding / 频次统计)

  • 方法
    • 计算 ID 在历史数据上的某些统计值,如点击率、转化率、均值等。
    • 例如 item_id 的点击率:
      C T R ( i t e m ) = 点击次数 曝光次数 + λ CTR(item) = \frac{\text{点击次数}}{\text{曝光次数} + \lambda} CTR(item)=曝光次数+λ点击次数
    • 这里的 λ \lambda λ 是平滑系数,避免数据稀疏问题。
  • 优点
    • 直接利用历史行为信息,有一定的业务可解释性。
  • 缺点
    • 需要对新 ID 做平滑处理,否则可能无法处理冷启动问题。
    • 可能会引入信息泄露(Target Leakage),需要 K 折交叉验证。

3.2. 连续值分桶的原因

(1) 处理长尾分布

  • 连续值(如消费金额、活跃天数)可能呈 长尾分布,极值影响较大。
  • 通过 分桶(Binning),可以减少异常值的影响,提高模型的稳健性。

(2) 提高模型的表达能力

  • 线性模型 只能学习 线性关系 ,但许多连续变量对目标的影响可能是 非线性的
  • 通过 分桶 + One-Hot/Embedding 处理,可以让模型学习非线性特征。

(3) 降低计算复杂度

  • 连续值直接输入可能导致特征维度过大(特别是高精度浮点数)。
  • 分桶后,连续特征变为有限个类别特征,减少计算量。

(5) 适用于深度学习

  • 在深度学习模型(如 DNN、Wide & Deep)中,连续值经过 分桶 + Embedding 处理,可以提升模型的泛化能力。

3.3 分桶(Binning)的常见方法

(1) 等宽分桶(Equal Width Binning)

  • 方法 :按照固定宽度进行分桶,例如 [0, 10][10, 20]
  • 缺点:如果数据分布不均匀,部分桶可能数据较少,影响学习。

(2) 等频分桶(Equal Frequency Binning)

  • 方法 :保证每个桶中的样本数相同,例如按 百分位数(quantile) 进行划分。
  • 优点:适用于长尾分布数据,每个桶的样本量均衡。

(3) 哈希分桶(Hash Binning)在推荐系统中的应用

Ⅰ. 为什么使用哈希分桶?

在处理 ID 类特征 (如用户 ID、商品 ID)或 高基数离散特征 (如 IP 地址、设备型号)时,直接使用 One-Hot 或 Embedding 会带来 维度爆炸存储开销过大 的问题。

哈希分桶(Hash Binning)是一种 高效降维避免存储过大的方法,常用于推荐系统和大规模机器学习任务。

Ⅱ. 哈希分桶的基本方法

哈希分桶(Hash Binning)主要基于哈希函数,将原始 ID 或类别特征映射到固定数量的桶中。

(1) 哈希映射(Hashing Trick)
  • 通过哈希函数 h(x)高维类别特征 映射到 固定数量的桶(buckets)
    b u c k e t = h ( I D ) m o d    B bucket = h(ID) \mod B bucket=h(ID)modB

    其中:

    • h(ID) 是哈希函数(如 MurmurHash, MD5, SHA-256)。
    • B 是桶的数量(通常 B << N,即桶数远小于 ID 总数)。
  • 这样,即使 ID 总数 N 很大 ,最终的桶数 B 仍然是有限的,避免了 维度爆炸

(2) 哈希 Embedding
  • 传统 Embedding 需要为每个 ID 训练一个独立向量:
    • 问题 :如果 ID 种类过多(如 1 亿用户),Embedding 需要 大量存储
  • 通过 哈希分桶 + Embedding
    • 先用哈希分桶减少 ID 维度,再为每个桶学习 Embedding。
    • 优点:减少存储需求,计算更加高效。
    • 缺点 :可能不同 ID 被映射到同一桶,导致 哈希冲突(Hash Collision)

四、手撕 sqrt(x)一牛顿迭代法、梯度下降法

4.1. 牛顿迭代法(Newton's Method)

4.1.1 基本思想

牛顿迭代法(Newton's Method)是一种用于求解非线性方程 f ( x ) = 0 f(x) =0 f(x)=0 的数值方法,基于 泰勒展开 的近似,利用导数信息进行快速逼近。

对于一个函数 f ( x ) f(x) f(x),使用一阶泰勒展开:
f ( x ) ≈ f ( x n ) + f ′ ( x n ) ( x − x n ) f(x) \approx f(x_n) + f'(x_n) (x - x_n) f(x)≈f(xn)+f′(xn)(x−xn)

令 f ( x ) = 0 f(x) = 0 f(x)=0,得到更新公式:
x n + 1 = x n − f ( x n ) f ′ ( x n ) x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} xn+1=xn−f′(xn)f(xn)

这个公式表示在点 x n x_n xn 处找到 切线 ,并用它的零点作为下一个迭代值。

4.1.2 用牛顿法求解平方根

假设我们要求 y = x y = \sqrt{x} y=x ,可以转化为方程:
f ( y ) = y 2 − x = 0 f(y) = y^2 - x = 0 f(y)=y2−x=0

求导数:
f ′ ( y ) = 2 y f'(y) = 2y f′(y)=2y

代入牛顿迭代公式:
y n + 1 = y n − y n 2 − x 2 y n y_{n+1} = y_n - \frac{y_n^2 - x}{2y_n} yn+1=yn−2ynyn2−x

化简:
y n + 1 = 1 2 ( y n + x y n ) y_{n+1} = \frac{1}{2} \left( y_n + \frac{x}{y_n} \right) yn+1=21(yn+ynx)

这就是牛顿迭代法求平方根的核心公式

4.1.3 牛顿法特点

优点
  • 二次收敛 :每次迭代误差缩小 平方倍,非常快。
  • 适用于非线性方程:可以求解平方根、对数、三角函数等复杂函数的零点。
  • 数值稳定:一般情况下比梯度下降更稳定。
缺点
  • 需要计算 导数 f ′ ( x ) f'(x) f′(x),有时比较复杂。
  • 依赖初值,如果初始点选得不好,可能收敛慢或不收敛。

4.2. 梯度下降法(Gradient Descent)

4.2.1 基本思想

梯度下降法(Gradient Descent)是一种 优化方法 ,用于找到函数的最小值。核心思想是:

  • 计算函数的 梯度(导数)
  • 沿着 梯度的相反方向 更新变量,使得函数值下降。

假设目标函数是:
f ( y ) = y 2 − x f(y) = y^2 - x f(y)=y2−x

其梯度(导数)为:
∇ f ( y ) = 2 y \nabla f(y) = 2y ∇f(y)=2y

按照梯度下降的更新规则:
y n + 1 = y n − α ⋅ ∇ f ( y n ) y_{n+1} = y_n - \alpha \cdot \nabla f(y_n) yn+1=yn−α⋅∇f(yn)

其中 α \alpha α 是学习率(learning rate),控制步长大小。

4.2.2 用梯度下降法求平方根

如果要求 y = x y = \sqrt{x} y=x ,可以改写目标函数:
f ( y ) = ( y 2 − x ) 2 f(y) = (y^2 - x)^2 f(y)=(y2−x)2

对 y y y 求导:
d d y f ( y ) = 2 ( y 2 − x ) ⋅ 2 y = 4 y ( y 2 − x ) \frac{d}{dy} f(y) = 2(y^2 - x) \cdot 2y = 4y(y^2 - x) dydf(y)=2(y2−x)⋅2y=4y(y2−x)

更新公式:
y n + 1 = y n − α ⋅ 4 y n ( y n 2 − x ) y_{n+1} = y_n - \alpha \cdot 4y_n (y_n^2 - x) yn+1=yn−α⋅4yn(yn2−x)

4.2.3 梯度下降法特点

优点
  • 适用于 任意可微函数 ,可以用来求解 最优化问题(如机器学习中的参数训练)。
  • 简单易实现,只需要计算一阶导数。
缺点
  • 收敛速度慢 ,相比牛顿法通常需要 更多迭代 才能逼近正确值。
  • 需要 调整学习率 α \alpha α:
    • 学习率太大:可能震荡或发散。
    • 学习率太小:收敛速度很慢。
  • 可能 陷入局部最优,特别是在非凸优化问题中。

4.3. 牛顿法 vs 梯度下降法

方法 适用场景 计算复杂度 收敛速度 依赖初值 适用范围
牛顿法 求解方程零点 需要计算二阶导数 二次收敛(快) 需要好初值,否则可能不收敛 适用于数值计算
梯度下降 求解最优化问题 只需计算一阶导数 线性收敛(慢) 对初值不敏感,但收敛速度受学习率影响 适用于机器学习和深度学习

4.4. python代码实现

python 复制代码
# 使用牛顿法求解 sqrt(x)
def sqrt_newton(x, tol=1e-6, max_iter=100):
    if x < 0:
        raise ValueError("Cannot compute the square root of a negative number")
    
    y = x  # 初始猜测值
    for _ in range(max_iter):
        y_next = 0.5 * (y + x / y)  # 牛顿迭代公式
        if abs(y_next - y) < tol:
            break
        y = y_next
    return y

# 使用梯度下降法求解 sqrt(x)
def sqrt_gradient_descent(x, alpha=0.01, tol=1e-6, max_iter=10000):
    if x < 0:
        raise ValueError("Cannot compute the square root of a negative number")
    
    y = x / 2  # 初始猜测值
    for _ in range(max_iter):
        gradient = 4 * y * (y**2 - x)  # 计算梯度
        y_next = y - alpha * gradient  # 梯度下降更新
        if abs(y_next - y) < tol:
            break
        y = y_next
    return y

# 测试
x = 25
print(f"牛顿法计算 sqrt({x}) = {sqrt_newton(x)}")
print(f"梯度下降法计算 sqrt({x}) = {sqrt_gradient_descent(x)}")
print(f"math.sqrt 计算 sqrt({x}) = {x ** 0.5}")  # 验证
相关推荐
1haooo4 分钟前
Mamba 模型:深度学习序列建模的新突破
python·深度学习·神经网络·计算机视觉·transformer
筑梦之月9 分钟前
常用密码学算法分类
算法·密码学
技能咖31 分钟前
2025春招市场迎AI热潮:生成式人工智能(GAI)认证如何重构人才竞争力
人工智能
篮l球场34 分钟前
搜索二维矩阵
算法
网安秘谈42 分钟前
密码学国密算法深度解析:SM2椭圆曲线密码与SM3密码杂凑算法
算法·密码学
2301_764441331 小时前
基于BERT的序列到序列(Seq2Seq)模型,生成文本摘要或标题
人工智能·python·深度学习·bert
说私域1 小时前
开源链动2+1模式与AI智能名片赋能的S2B2C共享经济新生态
人工智能·微信·小程序·开源
小羊在奋斗2 小时前
【算法】动态规划:回文子串问题、两个数组的dp
算法·动态规划