很多人以为数据分析就是会跑个Python脚本、调个参、画个图,然后得出“结论”。我以前也这么想,直到我接手了一个看似简单的“客户留存分析”项目,才发现自己天真得离谱。 那个项目让我认识到,真正的瓶颈根本不是算法,而是你根本不知道你的数据是从哪来的、中间经历了什么、缺失值到底意味着什么。这不是一句“清洗一下”就能解决的。 这种模糊的、像雾一样的“数据来历”,现在有个词叫“数据血缘”。听起来挺玄乎,但说白了,就是一份数据的身世档案。 可就是这份档案,几乎没人认真记。
事情是这样的:我拿到了两张大表,一张是用户注册表,一张是订单表。我想统计每个用户的首次下单时间,然后算各月的留存率。逻辑很简单,对吧?然后我用pandas去merge,结果行数一下子多了好几万,我下意识以为订单表有重复用户,就用了drop_duplicates,结果还是不对。 我折腾了三天,最后发现是注册表里同一个用户id对应了多个用户名(可能是改过名),而订单表里还有一部分订单根本没有关联上用户id,因为业务方把老系统的数据导过来时格式不一致。 更可怕的是,我后来问业务的人,他们说老系统的用户id是循环使用的,所以同一个数字在不同时间段代表不同的人。 我当时就懵了,这意味着我前面做的所有分析都是错的。这要是放在一个收入模型上,损失不敢想。我用Excel试过vlookup,比pandas更快发现异常,因为excel会直接显示#N/A,但没人告诉我这些#N/A代表什么。
这件事让我开始琢磨“数据血缘”到底有多重要。你以为只有那些大厂才需要吗?不,小团队更惨。 没有文档,没有注释,全靠某位离职的大哥脑子里的记忆。我试着用了一些开源的治理工具,比如Amundsen、DataHub,装起来倒也还行,但配置那些元数据采集和血缘图谱的时候,我发现我们根本没有一个统一的查询入口,数据散落在hive表、postgresql、还有几个csv文件里。 工具再强,也理不清这种“野生”数据。后来我想了个笨办法:用Git管理所有SQL脚本,在脚本头写清楚来源和清洗规则,并且在每次产出报表的同时,写一个“数据说明.md”放到同一个仓库里。 这么做看起来土,但起码后续接手的同事能顺着Git历史看懂来龙去脉。我还专门做了一个“字段字典”的csv,每个字段有含义、类型、取值范围、是否可空,以及对应业务口径。有了这些,我再去跑分析,心里踏实多了。
最后我想说,许多人追求算法模型的精度,却忽略了数据本身的“上下文”。模型可以复现,代码可以review,数据却像水一样,流过去就变了样。没有数据血缘,你的分析结果就是无根浮萍,也许碰巧对,但经不起追问。 如果你也想避坑,我以过来人的身份给你几条最接地气的建议:第一,为你手里最常用的几张表建一个字段字典,用csv也好,用dictionary文档也行,至少要有字段名、业务含义、是否可空、取值范围。 第二,每个SQL脚本开头写清楚数据来源和清洗逻辑,别嫌啰嗦,三个月后的你肯定会感谢现在的你。 第三,如果公司有条件,用git管理脚本和字典的变更,每次改口径都留个commit记录。这些事看起来没用,做起来麻烦,但有一天当你需要复盘一个半年前的指标时,你会像我一样庆幸自己做了这些。 我甚至觉得,未来数据分析师的核心能力不是写代码,而是寻找“数据真相”的能力——搞清楚每一列数据背后活生生的人和规则。这听起来不酷,但真的很重要。