异常值识别:一份踩坑后的经验笔记
去年整理某城市地铁客流量时,碰到一个诡异的日子:单日进站量比前后两周均值高出47%。第一反应是数据接口出了问题,排查后发现是当天有大型演唱会散场。如果直接按规则剔除,就会丢掉一个真实事件。这件事让我重新审视异常值识别——它不只是技术活,更是一个判断问题。
最直观的方法是看走势。把时间序列画出来,人眼对突起的尖峰或深坑很敏感。比如某电商平台日订单量长期在8万到12万之间波动,突然某天跳到25万,这种偏离幅度用肉眼就能锁定。但视觉判断的麻烦在于,当数据量达到几十万条或者波动本身很大时,眼睛会疲劳。这时候需要把走势转成可量化的指标,比如滚动均值和滚动标准差。
3σ原则是入门工具。假设数据近似正态分布,超出均值±3倍标准差的值可以标记为异常。某次分析用户停留时长,均值12分钟,标准差3.5分钟,那么超过22.5分钟的样本会被自动标出。但现实数据往往不服从正态分布,长尾效应明显。这时3σ会漏掉很多该抓的点,或者把正常的长尾用户误伤。更稳妥的做法是结合四分位距(IQR),把超过Q3+1.5倍IQR或低于Q1-1.5倍IQR的值列为疑似异常。这个方法对偏态分布更宽容。
阈值不是固定的。同一套指标,在促销期和平销期应该用不同的标准。我们曾经对某APP的日活做监测,平时用3σ,大促期间把阈值放宽到4σ,否则每天都会触发几十条告警,运营同事很快就麻木了。反过来,在数据质量排查阶段,可以把阈值调紧,宁可错杀也要先把可疑点捞出来。关键是想清楚:这次识别是为了找错误,还是为了找机会?目的不同,阈值松紧完全相反。
识别出异常值之后,更重要的动作是分类。我习惯把它们分成三类:第一类是采集错误,比如传感器断连导致的连续零值,或者日志重复写入造成的翻倍;第二类是业务真实波动,比如突发的舆情事件、竞品动作、政策调整;第三类是黑天鹅,从未出现过的新模式。分类决定了后续动作——第一类直接修正,第二类纳入观察,第三类则需要单独建立预测模型。
有个教训值得记下来。某次分析广告点击率,发现某渠道的点击率是其他渠道的6倍。团队一度想把它作为优质渠道放大投放。后来查了埋点日志,发现该渠道的点击事件被重复上报了三次。如果只看数字大小,很容易做出错误决策。异常值本身没有对错,它只是一个提示:这里和别处不一样。至于这个“不一样”意味着什么,必须回到业务现场去找答案。
现在我的习惯是,每次清洗完数据,不急着删掉异常点,而是单独存一张表,标注识别方法和初步判断。过一段时间回头看,有些当时觉得是噪声的点,后来被证明是趋势转折的早期信号。比如某产品日活连续三天下跌超过20%,按3σ规则被标记,当时判断是服务器波动。一周后复盘,其实是竞品上线了同类功能。异常值识别不是一次性动作,它应该嵌入到日常的数据观察流程里,和走势跟踪、预测校准放在一起看。
最后想说的是,方法只是工具。3σ、IQR、孤立森林、DBSCAN,这些算法各有适用场景,但没有哪个能替代对业务的理解。数据里的异常,往往是现实世界在向你招手。识别出来只是第一步,愿意花时间去追问“为什么”,才是让数据真正产生价值的地方。