---
name: 归因与变化分析（代码驱动）
description: 归因、拆解、驱动因素类问题的分析方法指引。平台不内置任何分析算法，分析必须由生成代码基于已锁定快照完成，并按分析结果契约输出可校验的产物。
code: attribution-analysis
phases:
  - PRE_PLAN
  - POST_EXECUTE
version: 1.0
---

# 归因与变化分析（代码驱动）

## 立场

**平台不提供归因算法。** 归因、结构拆解、量价分解、驱动因素排序都属于"分析方法"，
必须由你生成 Python 代码，在沙箱内基于 `input/` 中已物化的结果快照完成计算。

平台只做三件事，这三件事决定了你的代码要怎么配合：

1. 把本次查询的锁定结果物化成 `input/artifact_N.csv` 与 `.json`，并用 `input/manifest.json` 描述；
2. 校验你写到 `output/analysis.json` 的产物是否满足**分析结果契约**；
3. 对你**自报的断言（claims）**逐条复算——声称成立的等式必须真的成立。

因此：不要指望平台替你算，也不要在回答里凭感觉写"主要原因是 X"。
所有结论必须来自代码算出来的数，并且能被平台的复算验证。

## 规划前审计（PRE_PLAN）

动手写分析代码之前，先确认以下四件事，缺一件就不要硬算：

1. **周期是否可比**：本期与上期必须等长对齐；未完结周期的右边界是否按主题规则截断。
2. **指标是否可加**：只有"总额型"指标才能按维度取值直接相加分解。
   比率、均值、去重计数**不可加**——对它们做加法分解是错的，应当改用加权或结构分解。
3. **维度是否来自已确认口径**：拆解维度必须是主题语义包或字段说明里登记过的字段，不得凭空造维度。
4. **快照是否够用**：现有结果快照里是否已有分解所需的字段与粒度；
   缺字段时应报告能力缺口并说明需要补充什么，不得捏造数据。

## 常用分解方法（写代码时按需选择，不是固定套路）

| 场景 | 方法 | 关键恒等式 |
| --- | --- | --- |
| 总额变化按维度拆 | 加法分解 | Σ各维度变化量 = 总变化量 |
| "谁拉动、谁拖累" | 增长贡献分解 | 各驱动贡献(pp)之和 = 整体增长率 |
| 乘积型指标（金额=量×价） | 乘法分解 | 交互项必须显式归属，不得丢弃或归零 |
| 多层级定位根因 | 层级分解 | 每层子项之和 = 上层变化量 |

要点：

- **交互项**（例如 Δ量×Δ价）是真实存在的变化，必须显式分配给某个因子，
  并在 `notes` 里说明归属策略。悄悄丢掉会让各部分之和对不上总数。
- **比率类指标**不要用加法分解；若要解释比率变化，用加权分解或结构分解，并说明权重来源。
- **正负相抵**时，"占净变化"份额会失真（分母接近 0）。
  此时应改用"占变动总量"的份额口径来回答"谁影响最大"。

## 输出契约（必须遵守）

把结果写到 `output/analysis.json`：

```json
{
  "version": 1,
  "kind": "ATTRIBUTION",
  "metric": { "label": "指标名", "unit": "单位", "isRate": false },
  "periods": { "current": "本期", "previous": "上期" },
  "totals": { "base": 0, "current": 0, "delta": 0 },
  "rows": [
    { "key": "分组键", "label": "分组显示名", "base": 0, "current": 0,
      "delta": 0, "contribution": 0, "share": 0,
      "direction": "INCREASE", "note": "" }
  ],
  "claims": [
    { "code": "ADDITIVE", "row": "contribution", "total": "delta" },
    { "code": "SHARE_SUM", "scale": 1 },
    { "code": "DELTA_CONSISTENT" }
  ],
  "notes": ["口径说明、假设与局限"]
}
```

规则：

- 只有确实成立时才声明对应 claim；平台会逐条复算，不成立就整轮拒绝。
- `share` 的分母必须明确：占净变化，还是占变动总量。两者不要混用。
- 不确定的结论不要写进 `rows`；写进 `notes` 说明局限，宁可少说也不要说错。
- 任何 `NaN` / `Infinity`、任何用现有数据撑不住的数，都会导致结果被拒绝。

## 结果验证（POST_EXECUTE）

回到用户之前，自查：

1. 各部分之和是否等于总数（平台已复算，但你写码时就该保证，不要等它报错）；
2. 每个"原因"是否都能落到一个具体的数和一个具体的维度值；
3. 周期是否对齐、右边界是否截断、口径是否来自主题语义包；
4. 是否把"相关"说成了"因果"。数据只能支撑"这个维度贡献了多少变化"，
   不能支撑"因为 A 所以 B"。需要因果结论时，明确说明还缺什么证据。
5. 结论里不要复述过程。一句话结论 + 关键数 + 口径说明即可。

## 禁止事项

- 禁止在代码里重新访问数据库、拼 SQL 或重新取数，只能用 `input/` 里的快照。
- 禁止把业务词、枚举归并、公式、默认口径写死在分析代码里——它们只能来自主题语义包或字段说明。
- 禁止用"大概是、可能是、估计是"这类含糊表述充当归因结论。
- 禁止在数据不足时编造驱动因素；应当报告能力缺口并说明需要补充什么口径。
