【数据建模入门】从一家小店看懂数仓与机器学习:先理业务,再串技术

学习数据建模时,很容易先遇到一串术语:事实表、维度表、RFM、特征、标签、训练集。知道定义之后,仍然不清楚它们为什么存在,更不知道怎样连接起来。

理解这些概念,可以先跟着一家小店走一遍经营过程:先看清业务,再推导需要的数据,最后理解技术怎样支撑判断与行动。

本文采用虚构的小店、人物和数据,所有小样本数字仅用于教学推导,不代表真实实验效果或 Kaggle 比赛成绩。文末附复习章节,方便以后快速找回整条逻辑。

文章目录

    • 一、完整用户故事:店主怎样从账本走到客户经营
      • [1. 两个问题,开启一条业务链](#1. 两个问题,开启一条业务链)
      • [2. 看账本:先弄清楚记录代表什么](#2. 看账本:先弄清楚记录代表什么)
      • [3. 算交易:先约定口径,再讨论数字](#3. 算交易:先约定口径,再讨论数字)
      • [4. 看客户:交易额背后是怎样的购买关系](#4. 看客户:交易额背后是怎样的购买关系)
      • [5. 做客户维护:先弄清楚名单要服务什么目标](#5. 做客户维护:先弄清楚名单要服务什么目标)
      • [6. 判断未来:站在当时,只看当时知道的事](#6. 判断未来:站在当时,只看当时知道的事)
      • [7. 观察结果:名单命中,不等于维护产生增量](#7. 观察结果:名单命中,不等于维护产生增量)
    • 二、从业务问题推导数仓:先把事实组织清楚
      • [1. 为什么先分清业务事件](#1. 为什么先分清业务事件)
      • [2. 粒度:一行到底代表什么](#2. 粒度:一行到底代表什么)
      • [3. 事实、维度、指标分别承担什么责任](#3. 事实、维度、指标分别承担什么责任)
      • [4. 为什么金额能加,客户数不能随意加](#4. 为什么金额能加,客户数不能随意加)
      • [5. 为什么SQL能运行之后,还必须对账](#5. 为什么SQL能运行之后,还必须对账)
    • 三、从客户经营推导机器学习:把未来问题定义清楚
      • [1. 为什么要从交易明细转换到客户状态](#1. 为什么要从交易明细转换到客户状态)
      • [2. RFM:把业务猜想变成可检验信息](#2. RFM:把业务猜想变成可检验信息)
      • [3. 标签和窗口:怎样定义"再次购买"](#3. 标签和窗口:怎样定义“再次购买”)
      • [4. 模型怎样学习:用一个可手算的例子](#4. 模型怎样学习:用一个可手算的例子)
      • [5. 为什么需要训练、验证和测试](#5. 为什么需要训练、验证和测试)
      • [6. 为什么先有普通基线,再谈复杂模型](#6. 为什么先有普通基线,再谈复杂模型)
      • [7. 名单评价怎样连接业务预算](#7. 名单评价怎样连接业务预算)
      • [8. 预测闭环与经营闭环还差哪一步](#8. 预测闭环与经营闭环还差哪一步)
    • 四、业务与技术怎样接成一条执行链
    • 五、复习章节:十分钟找回整条逻辑
      • [1. 一分钟主线](#1. 一分钟主线)
      • [2. 概念速查:一个词找回一个问题](#2. 概念速查:一个词找回一个问题)
      • [3. 五个容易混淆的地方](#3. 五个容易混淆的地方)
      • [4. 十分钟复习法](#4. 十分钟复习法)
    • 参考资料

一、完整用户故事:店主怎样从账本走到客户经营

1. 两个问题,开启一条业务链

小林经营一家卖杯子和盘子的小店。杯子每个10元,盘子每个20元。每天有人购买,偶尔有人取消订单,也有客户隔一段时间再来。

3月底,她准备安排下个月的经营工作,想弄清楚两件事:

这个月的交易情况怎样?下个月人员有限,应该怎样安排老客户维护?

第一个问题需要把已经发生的事情算清楚。第二个问题需要根据现有信息,对接下来可能发生的事情作判断。

在这个故事里,小林提出经营目标,数据整理人员核对账本,店员执行客户维护。店小的时候,这三个角色也可能由同一个人承担,但各自需要回答的问题仍然不同。

2. 看账本:先弄清楚记录代表什么

下面是2011年3月的简化账本:

日期 单据号 客户 商品 数量 单价 行金额
3月1日 1001 小王 杯子 2 10 20
3月1日 1001 小王 盘子 1 20 20
3月20日 1002 小王 杯子 1 10 10
3月21日 C1002 小王 杯子 -1 10 -10
3月2日 1003 小李 杯子 1 10 10
3月15日 1004 小张 盘子 2 20 40
3月28日 1005 小张 杯子 1 10 10
3月31日 1006 小赵 盘子 1 20 20
3月5日 1007 小陈 杯子 1 10 10
3月10日 1008 未知 杯子 1 10 10
3月12日 1009 小李 杯子 1 0 0

小王的1001单据出现两行,因为一张订单买了两种商品。它代表一张订单、两条商品明细,不能把两行直接算成两张订单。

C1002在本例中约定为一条取消记录,并已确认对应1002。真实系统应通过原交易关联字段确认对应关系,不能仅凭编号相似或金额相同自行配对。

客户未知的那笔购买,商品和金额仍有记录,不能因为不知道是谁买的,就把这笔金额丢掉。

零元杯子可能是赠品,也可能是录入问题。账本不足以解释原因,因此先保留,单独检查,暂不计入本次付费购买统计。

3. 算交易:先约定口径,再讨论数字

为了回答"3月交易情况怎样",小林和数据整理人员约定:正数量、正价格的普通购买计入正向交易;取消单独计算;零价记录单列。

按这个口径:

text 复制代码
正向交易额 = 150元
取消金额   = -10元
净交易额   = 150 - 10 = 140元

正向付费购买订单数 = 8张
已知购买客户数     = 5人

8张订单中,有一张客户未知。已知客户只有5人,是因为小王、小张各下了两张订单。

140元有了清楚含义,但它仍不能直接叫利润。账本没有商品成本、运费等信息,也没有完整的支付与履约记录,因此这里只讨论约定口径下的交易净额。

4. 看客户:交易额背后是怎样的购买关系

小林继续追问:"这些交易是很多人各买一次,还是有些人反复回来买?"

整理后,客户行为如下:

客户 3月正向付费购买订单数 需要注意的情况
小王 2 第二笔后来取消
小李 1 零价记录未计入
小张 2 两笔购买记录
小赵 1 3月31日刚购买
小陈 1 3月5日购买

"买过两次"可以表达不同问题。如果研究客户曾经发起过几次购买,小王算两次;如果研究最终保留了几次未取消购买,就需要扣除已经可靠匹配的取消。

本例先研究正向购买行为。因此,五位已知客户中,两位出现过至少两次购买订单,观察比例为40%。后面的购买次数与预测标签也沿用这一事件定义。

这个比例描述3月已有历史,不能直接解释为"未来30天有40%的客户会购买"。它还不能说明客户为什么回来、维护工作是否有效。

5. 做客户维护:先弄清楚名单要服务什么目标

4月有新品到店,小林希望店员介绍给老客户,但只能先联系两个人。

"应该联系谁"看似是一个问题,实际上可能有不同目标:

目标 需要判断什么
尽量遇到会购买的人 谁本来就较可能购买
唤回沉默客户 谁较久没买,又值得维护
通过联系增加购买 谁会因为联系而改变行为

这三种名单未必相同。经常购买的人可能分数很高,但即使不联系,也可能自己回来。

目前只有交易账本,没有过去的联系及响应记录。小林因此先限定任务:根据截至4月1日的历史,判断未来30天哪些已知老客户较可能再次购买,作为名单参考。

这份判断先解决"可能会买",还没有解决"联系能多带来多少购买"。

6. 判断未来:站在当时,只看当时知道的事

假设这五位客户1月和2月没有其他购买,表中时间统一按当天零点处理。4月1日,五位客户的历史状态如下:

客户 距最近一次购买 过去90天购买订单数 正向购买金额
小王 12天 2 50元
小李 30天 1 10元
小张 4天 2 50元
小赵 1天 1 20元
小陈 27天 1 10元

小王的正向购买金额为50元,扣取消后的净额为40元。这里选择前者描述购买行为;如果改用净额,也要重新明确口径并一致执行。

这些状态支持一些猜想:购买频繁可能意味着持续需求,最近购买可能意味着仍然活跃。但客户也可能刚买够,短期不需要再买,所以猜想必须接受后续数据检验。

小林因此回看更早的历史:当时具有这些特点的客户,后来是否真的又买了?

7. 观察结果:名单命中,不等于维护产生增量

假设根据更早历史形成的判断,这次把小王和小张排在前面。4月结束后,观察到小王、小张、小赵都再次购买,小李、小陈在窗口内没有购买。

这份两人名单找到了两位购买者,但漏掉小赵。它有一定识别作用,却没有找到所有后来购买的人。

即使店员确实联系了名单中的两人,也不能据此说联系增加了两笔购买,因为他们可能本来就会买。

要检验维护是否有效,后续应在适合试验的人群中随机安排联系与暂不联系,记录购买、优惠和触达成本,比较两组结果。只有这样,才进一步接近"行动是否改善经营"的问题。

完整业务链由此形成:

text 复制代码
看清交易 → 理解客户 → 明确维护目标
→ 判断购买可能性 → 安排名单
→ 观察后续结果 → 检验行动效果

二、从业务问题推导数仓:先把事实组织清楚

1. 为什么先分清业务事件

现实交易可能经过下单、支付、发货、收货、取消或退款。不同事件表达不同状态:下单表示出现购买意向,支付表示收款,发货表示进入履约。

因此,计算前必须明确正在观察什么。本例账本只支持交易与取消分析,不能用一个金额字段替代支付、履约或利润的证据。

业务事件的定义,决定哪些记录可以放在一起计算。这是数仓设计的起点。

2. 粒度:一行到底代表什么

客户、订单和商品明细之间存在一对多关系:一位客户可以下多张订单,一张订单可以包含多条商品明细。

选择订单级保存,容易统计订单总额,却可能丢掉商品细节;选择商品明细级保存,可以分析商品,但计算订单数时需要去重。

本例保留商品明细,因为老板既看订单也看商品。明细可以向上汇总,只剩订单总额却通常无法还原商品构成。

粒度是在决定保留什么业务细节。它首先是一份业务约定,再落实为表结构。这也符合Kimball从业务过程、粒度、维度和事实逐步设计的思路。

参考:Kimball四步设计

原始行还应有稳定标识,例如来源文件与行号。单据号加商品号未必唯一;两行内容相同,也不能在缺少证据时直接认定为重复采集。

3. 事实、维度、指标分别承担什么责任

老板既要知道发生多少,也要知道是谁、何时、买了什么,并据此判断经营情况。

业务需要 专业设计 本例中的内容
保留发生的事件与数量 事实表 购买数量、金额、取消类别
按不同角度观察 维度表 日期、客户、商品
用一致口径评价 指标 月交易额、客户数、重复购买比例

事实记录"发生了什么",维度提供"从什么角度看",指标规定"怎样把事实变成经营数字"。

例如,"3月杯子的净交易额"就是日期限定3月、商品限定杯子,再按约定汇总正向与取消金额。

本例可以形成一套小型结构:

text 复制代码
原始交易:保留原始记录与来源
        ↓
交易事实:统一明细粒度、分类与金额
        ↓
日期 / 客户 / 商品维度:提供观察角度
        ↓
月交易汇总 / 客户行为汇总:服务经营分析

原始层负责追溯,事实层负责统一,汇总层负责服务具体问题。真实项目常使用ODS、DWD、DIM、DWS、ADS等名称,但应先理解责任,再记名称。

4. 为什么金额能加,客户数不能随意加

同一币种、同一口径下,不重叠月份的交易金额可以相加。但小王可能3月和4月都买,每月各算一位客户,合起来仍只有一个小王。

订单也会跨商品重复出现:1001同时含杯子和盘子,各商品组的订单数相加,会把1001算两次。

因此,金额、订单数、客户数和比例具有不同的汇总要求。复购比例还需要统一人群、事件及观察范围,不能把每月比例直接相加或随意平均。

这就是指标可加性背后的业务原因:汇总时,同一个业务对象是否会重复出现。

5. 为什么SQL能运行之后,还必须对账

如果商品维度错误地存了两条同编号杯子,交易按商品号连接时,一条记录可能被复制两次,金额随之放大。SQL可以正常执行,结果却错了。

因此,数仓至少要验证:

  • 原始记录是否保留,事实标识是否唯一。
  • 合格与隔离记录是否互斥且覆盖全部输入。
  • 维度编号是否唯一,连接前后事实行数是否一致。
  • 原始明细、事实表和汇总表的同口径金额是否相等。
  • 取消、零价和未知客户是否按约定处理。

这些检查共同守住一个条件:加工可以改变数据的组织方式,不能无依据地创造、删除或放大业务事实。

三、从客户经营推导机器学习:把未来问题定义清楚

1. 为什么要从交易明细转换到客户状态

交易明细围绕事件组织,客户维护围绕某个时点的决定组织。小林在4月1日判断小王,需要的是小王截至当时的状态,而非某一行杯子明细。

因此,一条预测样本表示:

某位客户,在某个预测时点,已经呈现出怎样的历史状态。

客户与时点缺一不可。同一个小王,3月1日和4月1日的历史不同,判断也可能不同。客户编号用于关联与生成名单,不应在这个练习中直接作为行为特征。

2. RFM:把业务猜想变成可检验信息

前面的三列客户状态,对应RFM:

特征 业务含义 希望检验的假设
R:Recency 距最近购买多久 最近活跃可能与后续购买有关
F:Frequency 一段时间买过几次 重复购买可能反映持续需求
M:Monetary 一段时间买了多少钱 购买规模可能包含需求信息

这些用于判断未来的信息,称为特征。模型要检验特征与目标的关系,不能预先假定R越小、F和M越大,未来概率一定越高。

耐用品客户可能刚买够,批发客户可能集中补货。理解这些业务机制,才能解释模型何时可能失效,而不是只记住三个字母。

3. 标签和窗口:怎样定义"再次购买"

本例将任务固定为:在2011年4月1日,对过去90天买过的已知客户,判断未来30天是否出现正向付费购买。

text 复制代码
历史窗口:[2011-01-01,2011-04-01)
未来窗口:[2011-04-01,2011-05-01)

左闭右开表示:恰好4月1日的购买属于未来结果,不属于历史;恰好5月1日的购买不属于这次标签。

未来窗口内发生符合定义的购买,标签为1,否则为0。只有取消、零价或其他不符合定义的记录,不产生正标签。

小李即使5月1日购买,本次仍标0。这个0只表示本窗口没有观察到购买,不能解释为永久流失。

如果数据只到4月15日,就不能把截至当日没买的人标为完整30天未购买。未来尚未观察完整,这类样本应等待或排除,而不能补成0。

4. 模型怎样学习:用一个可手算的例子

仅凭3月这11行,无法完成可靠训练。下面另外构造更早的教学历史样本,用汇总形式说明学习过程;它们不是前面账本直接计算的结果。

较早的客户状态 样本数 后来30天购买的人数 比例
过去90天买过1次 4 1 25%
过去90天买过2次 4 3 75%

一个简单分组模型可以得到:买过1次,估计概率25%;买过2次,估计概率75%。分组规则连接历史行为,组内后续购买比例提供概率估计。

真实算法会比较不同分割和特征。本例只保留一个分组,便于理解;每组只有4人,不能把这两个比例当成可靠、稳定的业务概率。

5. 为什么需要训练、验证和测试

4月1日作判断时不能知道4月答案,因此要先从更早历史学习,再按时间检验:

用途 示例预测时点 30天标签窗口结束点 作用
训练 2011-01-01 2011-01-31 学习规则与参数
验证 2011-02-01 2011-03-03 比较方案、决定选择
测试 2011-04-01 2011-05-01 检验冻结方案

每个时点都要有此前完整90天历史。训练标签在验证预测前闭合,验证标签也在最终预测前闭合,才能模拟现实的信息顺序。

如果把4月购买计入4月1日特征,或者在选择模型时反复查看测试答案,就会出现数据泄漏。标准化等预处理也应只在训练数据上学习,再应用到后续数据。参考:scikit-learn常见陷阱

6. 为什么先有普通基线,再谈复杂模型

不用机器学习,小林也可以采用"购买次数多的人优先"的规则。它就是一个基线,用来判断新方法是否真的带来价值。

延续手算例子,全部历史训练样本的购买比例为50%,因此可以建立"所有人都预测50%"的常数基线,再与25%/75%的分组模型比较。

假设独立验证样本如下:

过去90天购买次数 分组概率 实际是否购买
1 0.25 0
1 0.25 1
2 0.75 1
2 0.75 1

用预测概率与实际0/1的平方误差评价:

text 复制代码
常数基线平均误差 = 0.25

分组模型平均误差
= [(0.25-0)² + (0.25-1)² + (0.75-1)² + (0.75-1)²] / 4
= 0.1875

按这个预先选择的概率指标,分组模型在本次验证更好。于是固定规则,再评价4月结果;不能看完4月答案才修改规则,还把它称为独立测试。

7. 名单评价怎样连接业务预算

冻结模型给小王、小张75%,给小李、小赵、小陈25%。只能选择两人时,名单正好是小王和小张。

4月实际有三位购买者,其中两位在名单里:

text 复制代码
名单命中率 precision = 2 / 2 = 100%
购买者覆盖率 recall  = 2 / 3 ≈ 66.7%

命中率回答"选中的人里多少买了",覆盖率回答"所有买的人里找到多少"。小赵是被遗漏的购买者,说明只看频次并不充分,但是否增加其他特征仍需重新验证。

预算不同,评价也可能不同。整体排序更好的模型,在前两人名单上未必更好;概率误差更小,也不保证增加利润。最终要用对应业务目标的指标与普通基线比较。

本例人数极少,不支持稳定泛化结论或显著性判断。它只用于说明从业务约束推导评价方法的过程。

8. 预测闭环与经营闭环还差哪一步

交易历史能够支持"谁可能购买"的学习。要回答"联系是否增加购买",还需要行动记录、对照安排、成本和结果。

因此,当前数据与模型可以跑通历史预测闭环,但只有实际行动及效果证据加入后,才能评价客户维护的经营作用。

这也是Kaggle风格练习与真实业务的重要连接:前者训练特征、验证、基线和评估能力,真实经营还要检查目标、成本与因果效果。本文没有进行官方比赛提交。

四、业务与技术怎样接成一条执行链

把两种建模放在一起,可以看到清晰的责任衔接:

业务推进 专业问题 输出
看清交易 事件、粒度、分类 可信交易明细
理解经营与客户 维度、指标、汇总、对账 月报与客户分析
明确维护目标 人群、预测时点、未来窗口 预测任务定义
描述客户状态 历史汇总、RFM等特征 客户---时点样本
寻找判断依据 标签、训练、验证、基线 冻结的规则或模型
安排名单 预算、排序、评价指标 客户评分与名单
检验经营效果 行动记录、对照、成本 增量效果评价

最重要的连接点,是两边对"购买"使用同一个定义。不能在经营报表里排除零价赠品,却在预测标签里偷偷把它算成付费购买。

text 复制代码
原始交易
→ 统一事实与口径
→ 生成经营分析
→ 按预测时点汇总客户状态
→ 学习、验证并冻结方法
→ 输出名单
→ 记录行动与结果
→ 评价经营效果

技术选择也应沿着这条链展开:SQL与分析数据库承担交易加工、关联、汇总和窗口取样;Python与机器学习库承担模型拟合、评分与评估;调度及检查机制保证顺序、版本和失败状态可追踪。

在本地练习中,一套分析数据库与命令行脚本就能表达这些责任。数据规模、时效和协作要求增加后,再判断是否需要分布式计算、独立特征服务或其他基础设施。

五、复习章节:十分钟找回整条逻辑

1. 一分钟主线

发生了什么 → 客户呈现什么行为 → 接下来判断什么 → 怎样行动 → 如何确认有效。

复习问题 对应知识
这个月交易情况怎样? 事件、粒度、口径、对账
哪些客户重复购买? 客户汇总、去重、观察范围
未来谁可能再次购买? 样本、特征、标签、窗口
普通办法是否已经够用? 基线、验证、测试
名单是否符合预算目标? 命中率、覆盖率、成本
行动是否增加生意? 对照与增量效果

2. 概念速查:一个词找回一个问题

概念 用业务问题回忆
粒度 一行代表什么?
事实 发生了什么,数量和金额是多少?
维度 从谁、何时、什么商品等角度看?
指标口径 哪些计入,怎么算,范围是什么?
对账 加工前后的事实与金额是否一致?
样本 对谁,在什么时点判断?
特征 当时已经知道什么?
标签 事后用什么结果检验?
时间窗口 看此前多久,判断此后多久?
基线 普通办法能做到什么?
评价指标 什么结果符合当前目标?
增量效果 相比不行动,究竟多带来什么?

3. 五个容易混淆的地方

明细行数、订单数、客户数不同。它们在数不同的业务对象;一张订单可以有多行,一位客户可以有多单。

净交易额不能直接当利润。现有字段能证明什么,数字就应命名到什么程度。

历史复购比例不等于未来购买概率。人群、事件、时点与窗口必须分别说明。

模型指标更好不保证名单更有用。评价方式要对应预算和决策。

名单客户后来购买不能证明联系有效。自然购买与行动增量需要不同证据。

4. 十分钟复习法

前两分钟,闭卷讲业务。用自己的话说清楚小林先问什么、发现什么问题、怎样作判断、最后还缺什么证据。

接着三分钟,补回专业知识。写出"事件与粒度→统一口径与对账→客户状态→特征与标签→训练验证测试→名单→行动效果",解释每一步为什么存在。

最后五分钟,改变一个条件。从下面任选一题,先独立回答,再回看正文:

  1. 同一订单有三行商品明细,订单数怎样算?
  2. 客户编号缺失,哪些统计仍能做,哪些受影响?
  3. 客户在未来窗口结束后一天购买,本次标签是什么?
  4. 目标从找购买者变成发券增加利润,还缺哪些数据?
  5. 总体指标提高,但预算名单命中减少,该怎样解释?

判断是否掌握,可以尝试说完整这句话:

业务上遇到什么问题,所以需要什么设计;这个设计怎样解决问题,又不能证明什么。

例如:一张订单可以买多种商品,所以明细行数不等于订单数,需要按业务标识去重。这样能正确数订单,却不能证明订单已经支付或完成履约。

可以在学习后的第二天、隔几天、隔一两周各做一次闭卷回忆。先修正解释不清的地方,再阅读对应SQL与代码,让实现帮助检验理解。

参考资料

  1. Kimball:Four-Step Dimensional Design Process------对应业务过程、粒度、维度与事实的设计顺序。
  2. scikit-learn:Common pitfalls and recommended practices------对应预处理一致性、数据泄漏与训练/测试隔离。

文中零价处理、取消口径、90天历史、30天预测与小样本分组均为教学设定,不是通用业务规范。本文经AI辅助整理,并核对了教学口径、算术及概念关系;未将虚构示例表述为真实经营成效。

相关推荐
BJ_Bonree1 小时前
聊点技术 | Bonree ONE 业务链路观测实战 支付成功率下降,问题究竟出在哪一环?
大数据·人工智能
Bode_20021 小时前
TRIZ 理论知识体系与架构全景图
人工智能
richard_first1 小时前
第21章 训练一个简单的 GPT
人工智能·gpt·深度学习
FPGA信号处理1 小时前
【 凸优化】第六讲:求解器与支持向量机
算法·机器学习·支持向量机
专注仿真1 小时前
支持向量机(SVM)算法详解与代码实例
算法·机器学习·支持向量机
Highcharts.js1 小时前
Highcharts 集成到 React 或 Vue 项目中时,如何高效地使用 TypeScript技巧?
vue.js·人工智能·react.js·typescript·前端框架·highcharts
小lo想吃棒棒糖1 小时前
把 启元机器人Q1 的训练搬到昇腾 910B:从 MuJoCo 到 PPO 的一次完整迁移
人工智能·python·机器人·昇腾·具身智能
收放扳机1 小时前
PCB自动化整机“末端执行器”与“机械手负载”的匹配选型
人工智能·科技·自动化·制造·pcb工艺
IT_陈寒1 小时前
JavaScript实战技巧总结:深挖数组遍历的性能陷阱与实战解法
前端·人工智能·后端