一个团队决定让推荐模型更符合算法公平的要求。他们把地区字段从训练数据里删掉,重新跑了一遍特征重要性和整体指标,看上去确实比之前干净。但把结果按人群拆开,差距还在,在某些阈值下甚至更明显。
这不是罕见的失误。删字段是最容易做的动作,它给人强烈的完成感,却很少真正改变模型学到的关联。地区可以从设备型号、活跃时段、页面路径这些特征里被大致还原出来,它们和地区高度相关。模型并不需要那根被删掉的列。
被删掉的字段,换了个名字回来
这类间接还原出来的信息,通常称为代理变量。它的存在意味着:只处理表面字段,模型的判断依据几乎没变,只是绕了一圈。算法公平的讨论常在这里卡住,因为注意力放在了“模型不该看到什么”,而真正决定结果的是“数据里本来有什么”。
更麻烦的是,就算代理变量被处理干净,公平本身也不是一个能统一定义的目标。
几种“公平”,常常彼此打架
常见的说法至少有三种:
- 不同人群的通过率接近;
- 不同人群里的错误率接近,漏判和误判都不被系统性地放大;
- 同样的分数,在不同人群里对应相近的真实概率。
它们听起来都合理,但在多数现实设定下没法同时成立。要让通过率接近,通常得在分数线上做区分处理;要让错误率接近,分数线又得跟着各人群的分布移动;而一旦分数线不同,同一分数的含义就变了。三条路里通常只能走一条半。
所以真正要回答的问题,是“我们愿意为哪种公平,接受哪种误判”,而非“这个模型公平吗”。这听起来像绕口令,但它决定了后面所有的工程动作。
把选择放到桌面上
如果接受上面这个前提,一些做法会变得比较自然。
敏感字段不用于训练,但保留用于评估。删掉字段解决不了问题,留着它来量差距,才让问题可见。不少团队卡在这里:既怕它“污染”模型,又不敢完全失去观测能力,结果两头都没做到。
另一个动作是把指标按子群体拆分,而且拆到业务真正关心的那一段。整体准确率好看,往往是因为人群占比大的部分把数字撑住了,边角人群的问题被平均数吞掉。分层看错误率,比看一个总分有用得多。
还有一件事是记录阈值的取舍。为什么选这个点、代价是什么、谁签字同意,这些记录在一年后回看时,比多数模型文档都重要。它不是一次上线前的检查项,而是持续暴露在业务里的一个状态。
也有一些边界需要说清楚。没有标签的场景下,误差本身就没法准确估计;人群划分过细时,样本量不够,差异可能只是噪声。这种情况下,如实写出不确定性,比硬给一个结论更负责。
最难的部分不在代码里
见过几次这样的讨论:工程师把几种公平定义和对应代价列出来,会议室里沉默一会儿,然后有人问,能不能都满足。答案通常是不能。最后定下来的方案,往往不是技术上最干净的那个,而是业务、合规和产品都能接受的那个。
这也是我越来越觉得算法公平没法被当成纯技术任务的原因。它可以被测量、被监控、被写进流程,但最终的取舍发生在人之间。模型只是把那个取舍放大了,并且以很快的速度重复执行。