阿里国际・搜索广告算法

一、如何避免特征之间的多重共线性,避免了又会有什么缺点

1.1. 计算相关系数矩阵(如皮尔逊相关系数)

  • 使用 np.corrcoefpandas.corr() 找出高度相关(如 > 0.9)的特征对
  • 删除其中一个冗余特征或合并(如取平均)

1.2. 方差膨胀因子(VIF: Variance Inflation Factor)

  • VIF > 5VIF > 10 通常认为存在共线性,可使用 statsmodels 工具包计算:
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

1.3. 主成分分析(PCA)或线性降维

通过线性变换将数据投影到方差最大的方向,得到一组不相关的主成分

1.4. L1 正则化(Lasso)

自动进行特征选择,将一些权重为零

1.5. 可能存在的缺点

  • 信息损失:删除/合并特征可能丢掉对预测有帮助的微弱信号
  • 模型可解释性下降:如 PCA 后主成分难以直接解释
  • 泛化能力不一定提高:在部分深度模型中,共线性未必严重影响性能

二、XGBoost 是如何处理缺失值的?

XGBoost 在建模时具有内建的 缺失值处理机制,它不需要用户显式填补缺失值(如用均值、中位数等填充),而是通过以下方式自动处理:

2.1. 原理

在构建每棵树时,对于每一个分裂节点,XGBoost 会自动学习一个默认方向(default direction) 来处理缺失值。

👉 即:

  • 对于一个特征的某个分裂点(如 x ≤ t),
  • 如果某个样本该特征为缺失(NaN),模型会判断:
    • 让缺失样本走左子树更好,还是右子树更好?
  • 这个“更好”是通过提升后的 损失函数增益(Gain)最大化 来判断的。最终每个特征的每个节点,都会记录一个 缺失值应该走向哪一边 的默认路径。

2.2. 特点

  • 无需预处理:原始数据中保留 NaN 即可。
  • 每个节点独立学习缺失分支:不同树、不同特征、不同位置的缺失值走向可能不同。
  • 自动化、优化后的处理:提升精度同时降低人工处理成本。

三、说一下NCELoss和Sample softmaxloss的区别,Sample softmaxloss的消偏是怎么做的?

3.1. 背景:为何需要采样?

大词表/大类别推荐场景 中,全量 softmax 计算代价高昂(需计算所有类别得分并归一化),因此引入 负采样损失(Negative Sampling)。

3.2. NCELoss(Noise Contrastive Estimation Loss)

3.2.1. 原理:

NCE 把多分类任务转换为二分类任务:

目标:区分真实样本(positive)和从噪声分布中采样的负样本(noise)

  • 假设词表大小为 VVV,采样 kkk 个负样本 y1,...,yky_1,...,y_ky1,...,yk 来近似 softmax
  • 模型学习一个 判别器
    P(D=1∣x,y)=Pdata(y∣x)Pdata(y∣x)+k⋅Pn(y) P(D = 1 | x, y) = \frac{P_{\text{data}}(y|x)}{P_{\text{data}}(y|x) + k \cdot P_n(y)} P(D=1∣x,y)=Pdata(yx)+kPn(y)Pdata(yx)
    其中:
    • Pn(y)P_n(y)Pn(y):负样本的采样分布(通常为 unigram 或 log-unigram)
    • 使用 logistic regression 对 D∈{0,1}D \in \{0, 1\}D{0,1} 做分类

3.2.2. 缺点:

  • 目标函数是逼近 data distribution,而非逼近 softmax 概率
  • 训练和推理目标不一致(train for classification, infer for softmax)

3.3. NCELoss 伪代码(Noise Contrastive Estimation)

for (x, y_true) in dataset:
    # 1. 正样本打分
    s_pos = dot(embedding(x), embedding(y_true))
    # 2. 采样 k 个负样本 y_neg_i ~ P_n(y)
    y_neg_samples = sample_k_negatives(k)
    # 3. 计算负样本打分
    s_negs = [dot(embedding(x), embedding(y_neg)) for y_neg in y_neg_samples]
    # 4. 合并打分
    logits = [s_pos] + s_negs
    labels = [1] + [0] * k  # 正样本为1,其余为0
    # 5. 二分类损失(二元交叉熵)
    loss = binary_cross_entropy(logits, labels)

3.4. Sampled Softmax Loss(带偏差校正的采样 softmax)

3.4.1. 原理:

Sampled Softmax Loss 是 softmax 的近似形式,通过采样负类减少计算,但仍近似原始 softmax:
Softmax(y∣x)=exp⁡(sy)∑y′∈Vexp⁡(sy′)≈exp⁡(sy)exp⁡(sy)+∑y′∈Nexp⁡(sy′) \text{Softmax}(y|x) = \frac{\exp(s_y)}{\sum_{y' \in \mathcal{V}} \exp(s_{y'})} \quad \approx \quad \frac{\exp(s_y)}{\exp(s_y) + \sum_{y' \in \mathcal{N}} \exp(s_{y'})} Softmax(yx)=yVexp(sy)exp(sy)exp(sy)+yNexp(sy)exp(sy)

  • N\mathcal{N}N:采样的一小部分负类
  • sy=logit(x,y)s_y = \text{logit}(x, y)sy=logit(x,y)

3.5. 为什么要校正?

采样的负样本分布 q(y)q(y)q(y) 往往与真实 softmax 分布差异很大,导致偏差。
对 logits 加上 采样分布的概率校正项,即对每个负样本:
s~y=sy−log⁡q(y) \tilde{s}_y = s_y - \log q(y) s~y=sylogq(y)
其中 q(y)q(y)q(y) 是采样概率。
最终 softmax:
softmax(y∣x)=exp⁡(sy−log⁡q(y))∑y′∈pos∪negexp⁡(sy′−log⁡q(y′)) \text{softmax}(y|x) = \frac{\exp(s_y - \log q(y))}{\sum_{y' \in \text{pos} \cup \text{neg}} \exp(s_{y'} - \log q(y'))} softmax(yx)=yposnegexp(sylogq(y))exp(sylogq(y))
这个校正项使得采样 softmax 在理论上更加逼近全量 softmax。

3.6. Sampled Softmax Loss 伪代码

逼近原始 softmax,校正采样偏差

for (x, y_true) in dataset:
    # 1. 正样本打分
    s_pos = dot(embedding(x), embedding(y_true))
    
    # 2. 采样 k 个负样本 y_neg_i ~ q(y)
    y_neg_samples = sample_k_negatives(k)

    # 3. 所有样本合并(正 + 负)
    all_y = [y_true] + y_neg_samples

    # 4. 计算 logits
    logits = []
    for y in all_y:
        score = dot(embedding(x), embedding(y))
        bias_correction = -log(q(y))  # 消偏修正
        logits.append(score + bias_correction)
    # 5. 构造标签
    labels = [0]  # 正样本在第0位
    # 6. 交叉熵损失(对 softmax 分布)
    loss = softmax_cross_entropy(logits, labels)

3.6.1. q(y) 的计算和作用

在 Sampled Softmax Loss 中的 q(y) 是负样本采样分布(noise distribution),用来表示采样负样本的概率。它是消偏(bias correction)时用到的关键量。

  • 定义:q(y) 是从类别空间中采样负样本 y 的概率。

  • 一般取法

    • 基于 unigram 频率:用训练集中类别 y 出现的频率作为 q(y),即:
      q(y)=count(y)/totalcount q(y) = count(y) / total_count q(y)=count(y)/totalcount
    • 平滑频率:为了避免频率过小或过大,一般做幂平滑(power smoothing):
      q(y)=(count(y))α/sumi(count(i))α q(y) = (count(y))^α / sum_i (count(i))^α q(y)=(count(y))α/sumi(count(i))α
      其中 α ∈ (0,1),例如 0.75,是常见的平滑指数。
  • 作用

    • 负采样时依据 q(y) 采样负样本,越频繁的类别被采样概率越高。
    • 在 Sampled Softmax Loss 中,logits 需要减去 log q(y) 做偏差校正,避免采样偏差影响模型学习。

3.7. 总结对比

项目 NCELoss Sampled Softmax Loss
本质 分类任务(正 vs 负) Softmax 近似
是否校正偏差 ❌ 否(拟合二分类目标) ✅ 是(log 采样概率校正)
推理一致性 ❌ 不一致 ✅ 一致(训练/推理)
采样分布要求 灵活 需明确估计 q(y)q(y)q(y)
  • NCELoss 多用于 word2vec、representation learning 等 embedding 学习场景
  • Sampled Softmax 多用于大规模分类任务、推荐系统中的点击预测或召回任务中

四、如何利用计算机求π,不限时间复杂度,可以循环一亿次

4.1. 莱布尼茨级数(Leibniz series)

π=4∗(1−1/3+1/5−1/7+1/9−...)π = 4 * (1 - 1/3 + 1/5 - 1/7 + 1/9 - ... )π=4(11/3+1/51/7+1/9...)

pi = 0.0
sign = 1
for k in range(100_000_000):
    pi += sign / (2 * k + 1)
    sign = -sign
pi *= 4

4.2. 蒙特卡罗方法(Monte Carlo)

利用几何概率:在边长为1的正方形中随机采点,点落在内切圆内的概率是 π/4。

import random
inside = 0
total = 100_000_000
for _ in range(total):
    x = random.random()
    y = random.random()
    if x * x + y * y <= 1:
        inside += 1
pi = 4 * inside / total
print(f"Estimated π: {pi}")
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐