算法面试 / 03

采样偏差、数据泄漏与标签噪声

很多算法项目失败,不是因为模型不够强,而是数据有问题。面试官追问数据,是为了判断你有没有真实做过业务算法。

采样偏差

业务数据通常不是随机样本,而是历史策略产生的。

推荐系统只记录曝光过的内容,没曝光的不知道用户是否会点击。广告系统只记录竞价赢了的流量。风控系统拦截后,看不到放行后的真实风险。补贴系统只知道历史补贴策略下的行为。

如果直接用这些数据训练,模型会学习到历史策略偏差。

怎么回答

可以说:

我会先分析样本是如何被历史策略选择出来的。如果存在曝光偏差或选择偏差,会尝试引入随机探索流量、倾向得分修正、分层采样或反事实评估,至少在评估时分场景看模型是否只学到了旧策略。

数据泄漏

数据泄漏是训练时使用了线上预测时不可用的信息。

常见泄漏:

  • 使用了未来点击、成交、审核结果。
  • 特征统计窗口穿越。
  • 用户标签在样本时间之后才生成。
  • 训练集和测试集按样本随机切分,导致同一用户或同一事件泄漏。
  • 目标变量被间接编码进特征。

怎么回答

我会按时间切分数据,确保特征只使用预测时刻之前的信息。对统计特征会严格控制时间窗口,并检查训练、验证、线上服务的特征生成逻辑是否一致。

标签噪声

业务标签不一定可靠。

例如:

  • 点击不一定代表喜欢。
  • 没点击不一定代表不喜欢,可能位置太低。
  • 风控风险标签可能延迟出现。
  • 内容审核标签可能有人审标准不一致。
  • 用户取消订单可能由天气、商家、骑手等多因素造成。

标签噪声会让模型学习错误信号。

处理方法

  • 改进标签定义,比如用有效点击、停留时长、复访。
  • 多标签建模,区分短期行为和长期价值。
  • 对高噪声样本降权。
  • 引入人工校验或高置信样本。
  • 分场景评估,不只看整体指标。

训练线上不一致

训练和线上不一致是高频线上事故来源。

常见问题:

  • 离线特征有,线上实时拿不到。
  • 离线统计是全量,线上只能近实时。
  • 缺失值处理逻辑不同。
  • 类别映射版本不同。
  • 模型输入顺序不一致。

面试回答

我会保证训练和线上共用同一套特征定义,重要特征做一致性校验。上线前会做 shadow test,对比离线重放和线上实时输出,监控特征缺失率、分布漂移和模型分数分布。

负样本采样

推荐、广告、风控里负样本很关键。

负样本采得太容易,模型学不到区分能力;负样本采得太偏,线上泛化差。广告 CVR 还要注意只在点击后观察转化,天然有选择偏差。

面试里可以说:

我会根据业务目标选择负样本。排序任务里要关注曝光未点击、点击未转化、同 session 竞争样本等不同负样本,并通过采样权重或校准处理训练分布和线上分布差异。

一段总结回答

我会把数据问题分成三类:样本是否有选择偏差,标签是否准确,特征是否存在泄漏或训练线上不一致。处理上,先按时间切分和特征可用性避免泄漏,再通过分层采样、探索数据或倾向修正缓解偏差,最后用分场景评估和线上监控验证模型是否稳定。

偏差与过拟合(物流场景)

Q:解释混淆变量(confounding variable)、碰撞偏差(collider bias)和中介变量(mediator)各是什么,并举例说明。

来源:阿里巴巴 / 算法工程师 - 运筹 & 因果推断

普通回答:混淆变量是同时影响自变量和因变量的变量。

更好的回答

混淆变量:同时影响处理变量和结果变量的变量。例:天气同时影响骑手接单意愿(处理)和用户下单量(结果),不控制会导致伪相关。

碰撞偏差:同时被处理和结果影响的变量,条件化它会打开本来关闭的后门路径。例:”是否被评为优秀骑手”同时受接单量和服务评分影响,若只分析优秀骑手的数据,接单量和评分会呈现负相关。

中介变量:处理影响中介、中介再影响结果的变量。例:补贴 → 骑手出勤率 → 完单量,出勤率是中介。控制中介会阻断你想要测量的因果路径,需用中介分析框架(NDE / NIE)。

考察点:因果图中三种基本结构的区分,以及在业务数据中”该不该控制某变量”的判断力。

Q:过拟合的常见原因有哪些?在骑手行为预测模型中如何针对性地缓解?

来源:阿里巴巴 / 算法工程师 - 运筹 & 因果推断

普通回答:数据少、模型大,加 Dropout 和正则化。

更好的回答

常见原因:训练数据量不足、特征维度过高、模型容量过大、标签噪声、特征泄露。

物流场景针对性缓解

  • 数据层:数据增强(轨迹扰动)、样本重采样(平衡稀有天气和节假日)。
  • 特征层:特征选择(IV / SHAP)、去除高泄露特征(如未来信息)。
  • 模型层:Dropout、L1 / L2 正则、Early Stopping。
  • 评估层:时序分割验证,不能随机划分,否则训练集包含未来标签。
  • 集成:Bagging / Stacking 降低方差。

考察点:不是背定义,而是能否结合物流数据特点(时序性、长尾场景、天气等)给出有针对性的方案。

Q:给定骑手历史接单数据(rider_id, order_time, complete_time),用 Python 计算每位骑手的平均在途时长和高峰期(18:00-20:00)接单占比。

来源:阿里巴巴 / 算法工程师 - 运筹 & 因果推断

普通回答:用 for 循环逐条计算。

更好的回答

import pandas as pd

df = pd.read_csv('orders.csv')
df['order_time'] = pd.to_datetime(df['order_time'])
df['complete_time'] = pd.to_datetime(df['complete_time'])
df['duration'] = (df['complete_time'] - df['order_time']).dt.total_seconds() / 60

avg_duration = df.groupby('rider_id')['duration'].mean()

df['hour'] = df['order_time'].dt.hour
df['is_peak'] = df['hour'].between(18, 19)
peak_ratio = df.groupby('rider_id')['is_peak'].mean()

result = pd.DataFrame({'avg_duration': avg_duration, 'peak_ratio': peak_ratio})

注意 between(18, 19) 是闭区间,覆盖 18:00-19:59,即 18:00-20:00 时段。面试时主动说明这一点。

考察点:pandas 时间处理、groupby 聚合、between 的闭区间语义,以及数据处理的工程规范。

下一篇建议继续看: