The core goal of attribution analysis is to answer "why did the metric change." This is not a task that can be completed in a single step—it is adiagnostic process, requiring the integrated use of multiple analytical methods, ultimately converging into a complete attribution conclusion.
The diagnosis follows the logic of "first characterize, then locate, then find the cause": first figure out how much it changed (Step 1), then decompose which business link went wrong (Step 2), then locate the specific dimensions and dimension values (Step 3), then correlate external events to find the root cause (Step 4), and finally synthesize all findings to give a conclusion (Step 5).
┌───────────────────────────────────────────────────────────────┐
│ 归因诊断全流程 │
│ │
│ Step 1 确认波动事实 → 变了多少?跟什么比? │
│ ↓ │
│ Step 2 因子拆解 → 哪个业务环节出了问题?(定性) │
│ ↓ │
│ Step 3 维度归因 → 问题环节在哪些维度上集中?(定位) │
│ ↓ ↘ 发现集中点 → 继续下钻到更细维度 │
│ Step 4 外部事件关联 → 天气?节假日?竞对?行业政策?(找因) │
│ ↓ │
│ Step 5 综合诊断结论 → 汇总所有发现,输出归因报告 │
│ │
│ * 并非每次都需走完全部步骤,根据复杂度灵活调整 │
│ * 每步的发现逐步积累,最终在 Step 5 统一收口 │
└───────────────────────────────────────────────────────────────┘
Why factor decomposition (Step 2) before dimension attribution (Step 3)?
Factor decomposition answers "which link broke" (traffic? conversion? average order value?), while dimension attribution answers "where it broke" (which channel? which region?). Only after knowing which link went wrong does dimension attribution have direction—instead of blindly scanning all dimensions against the overall metric, you drill down precisely on the problem factor.
Example: GMV drops 10%. If you do dimension attribution directly, you might find "the Retail channel contributed 70% of the decline," but you still don't know whether Retail had less traffic or worse conversion. If you do factor decomposition first and find "the conversion rate decline is the main cause," then do dimension attribution on conversion rate, you directly locate "the Retail channel's conversion rate dropped 18% month-over-month." Each step narrows the scope, making it much more efficient.
Of course, if the metric has no clear business formula that can be decomposed (Step 2 not applicable), just skip to Step 3 and do dimension attribution.
0. Interface Information (Reuse Gateway API)
This Skill reuses the Gateway API system of metric-query. All API call rules are fully consistent with metric-query.
Gateway Search API (retrieve metrics and dimensions)
Search metrics: GET https://gateway.can.aloudata.com/api/metrics/search?keyword={关键词,可逗号分隔}&pageSize={数量}
Single-metric dimensions: GET https://gateway.can.aloudata.com/api/metrics/{metricName}/dimensions?keyword={可选过滤词,支持逗号分隔多关键词}
Batch metric dimensions: GET https://gateway.can.aloudata.com/api/metrics/dimensions?metricNames={指标1,指标2}&keyword={可选过滤词,支持逗号分隔多关键词}
Authentication method: all requests must carry an API Key, passed via the request header X-API-Key (it can also be passed via the ?apikey= query parameter). Missing or invalid Keys will return 401.
Calling iron rules:
- All requests must include the API Key authentication header
-H "X-API-Key: $CAN_API_KEY",$CAN_API_KEYread from an environment variable (the user needs to configure it in~/.openclaw/.envconfigured inCAN_API_KEY=cgk-xxxxxxxx) - Chinese URL parameters must be URL-encoded, using
--data-urlencode+-G
Example:
curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=5" --data-urlencode "keyword=销售额" -G curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/retail_amt/dimensions" # 维度多关键词过滤(逗号分隔,匹配任一即返回,匹配范围包括维度名/展示名/描述/维度值样本) curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/retail_amt/dimensions" --data-urlencode "keyword=渠道,地区,品牌" -G
Metric Query API (execute data queries)
Interface: POST https://gateway.can.aloudata.com/api/metrics/query
Pass the JSON body with heredoc (because timeConstraint contains single quotes, do not use -d '...'):
curl -X POST "https://gateway.can.aloudata.com/api/metrics/query" \
-H "X-API-Key: $CAN_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{JSON请求体}
EOF
The request body format is fully consistent with metric-query, and follow all 9 iron rules and construction specifications of the metric-query Skill (including NOW() usage, metricDefinitions registration, ratio/ranking pitfalls, heredoc parameter passing, etc.).
Step 1: Confirm the fluctuation facts
The starting point of attribution is to figure out "how much exactly changed" and "compared to what." Choose the wrong baseline and everything after is wasted.
1.1 Determine the comparison baseline
| User says | Comparison baseline | Implementation method |
|---|---|---|
| "decreased month-over-month" "compared with last month" | previous period | __sameperiod__mom__ series |
| "decreased year-over-year" "compared with last year" | same period last year | __sameperiod__yoy__ series |
| "how far from target" "missed target" | target value | requires the user to provide the target value, or retrieve it from the system |
| "why did it drop" (baseline not specified) | default to month-over-month | confirm with the user after inferring; if it involves a seasonal industry, recommend year-over-year |
when the user has not specified a baseline: do not assume directly; confirm with the user first. For example: "Is the decrease you mentioned compared with last month (month-over-month) or the same period last year (year-over-year)? If this industry has obvious seasonality, I recommend using year-over-year to rule out seasonal factors."
1.2 Query the overall change amount
After retrieving the metric through the Gateway, first check the overall change:
# 搜索指标
curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=5" --data-urlencode "keyword=销售额" -G
# 查整体环比变化
curl -X POST "https://gateway.can.aloudata.com/api/metrics/query" \
-H "X-API-Key: $CAN_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'EOF'
{
"metrics": ["retail_amt", "retail_amt__sameperiod__mom__value", "retail_amt__sameperiod__mom__growthvalue", "retail_amt__sameperiod__mom__growth"],
"timeConstraint": "DateTrunc(['metric_time'], \"MONTH\") = DATEADD(DateTrunc(NOW(), \"MONTH\"), -1, \"MONTH\")"
}
EOF
Output:clear numerical facts—the metric changed from X to Y, a change of Z (change rate W%). All subsequent analysis is based on this.
1.3 Observe the time trend (optional but recommended)
Check the trend over recent months to determine whether it is an abnormal fluctuation or a sustained trend:
{
"metrics": ["retail_amt"],
"dimensions": ["metric_time__month"],
"timeConstraint": "DateTrunc(['metric_time'], \"MONTH\") >= DATEADD(DateTrunc(NOW(), \"MONTH\"), -6, \"MONTH\") AND DateTrunc(['metric_time'], \"MONTH\") < DateTrunc(NOW(), \"MONTH\")",
"orders": [{"metric_time__month": "asc"}]
}
Step 2: Factor decomposition (qualitative—which business step went wrong)
First figure out "which step is broken" so that the subsequent dimensional attribution has a target.
2.1 Determine whether it applies
The prerequisite for factor decomposition is that the metric has a clear business formula.If there is a formula, this step must be done first; if there is none, skip directly to Step 3.
Common decomposition formulas:
| Composite metric | Decomposition formula | Factor meaning |
|---|---|---|
| GMV / sales | UV × conversion rate × average order value | traffic × conversion × price |
| sales | number of buyers × average order value | number of customers × price |
| sales | number of orders × unit price × attachment rate | order volume × price × purchase depth |
| profit | revenue - cost | revenue side vs cost side |
If the user has not explicitly given a formula, infer it based on business common sense and confirm with the user. For example, if the user asks "why did GMV drop", you can proactively propose: "Shall I decompose it by UV × conversion rate × average order value to see which step has the problem?"
2.2 Obtain factor data
Search the Gateway for the metrics corresponding to each factor, then query the values for the current period and the baseline period:
# 搜索相关因子指标
curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/search?pageSize=10" --data-urlencode "keyword=UV,转化率,客单价,购买人数" -G
{
"metrics": ["visitor_cnt", "buyer_cnt", "AOV",
"visitor_cnt__sameperiod__mom__value",
"buyer_cnt__sameperiod__mom__value",
"AOV__sameperiod__mom__value"],
"timeConstraint": "DateTrunc(['metric_time'], \"MONTH\") = DATEADD(DateTrunc(NOW(), \"MONTH\"), -1, \"MONTH\")"
}
If some factors do not have directly corresponding metrics, calculate using metricDefinitions + expr:
"metricDefinitions": {
"cvr": { "expr": "[buyer_cnt]/[visitor_cnt]" }
}
2.3 Calculate factor contributions
Multiplicative formula Y = A × B × C:
When the change rates of the factors are small (all < 20%), the approximation method can be used:
ΔY% ≈ ΔA% + ΔB% + ΔC% + 交叉项
A 对 Y 的贡献 ≈ ΔA% / ΔY%
When the change rates are large, use Shapley value decompositionto ensure accuracy:
import itertools, math
def shapley_decomposition(factors_base, factors_current):
"""
factors_base: dict, 如 {"UV": 10000, "CVR": 0.05, "AOV": 200}
factors_current: dict, 如 {"UV": 12000, "CVR": 0.045, "AOV": 210}
返回各因子对总变化量的 Shapley 贡献
"""
factor_names = list(factors_base.keys())
n = len(factor_names)
contributions = {}
for name in factor_names:
shapley_val = 0
others = [fn for fn in factor_names if fn != name]
for subset_size in range(n):
for subset in itertools.combinations(others, subset_size):
subset_set = set(subset)
val_with, val_without = 1, 1
for fn in factor_names:
if fn == name:
val_with *= factors_current[fn]
val_without *= factors_base[fn]
elif fn in subset_set:
val_with *= factors_current[fn]
val_without *= factors_current[fn]
else:
val_with *= factors_base[fn]
val_without *= factors_base[fn]
weight = math.factorial(subset_size) * math.factorial(n - subset_size - 1) / math.factorial(n)
shapley_val += weight * (val_with - val_without)
contributions[name] = shapley_val
return contributions
Additive formula Y = A + B + C: simply look at the change amount of each term; no complex decomposition is needed.
Mixed additive + multiplicative: first decompose additively, then apply Shapley to each multiplicative term separately.
2.4 Waterfall chart visualization
The results of factor decomposition are most intuitively presented using a **Waterfall Chart**—the starting point is the baseline value, the endpoint is the current-period value, and each segment in between represents the contribution of one factor, with positive contributions going up (green) and negative contributions going down (red). At a glance you can see which link is dragging things down and which link is holding things up.
Generate a waterfall chart using Python + matplotlib:
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
matplotlib.rcParams['axes.unicode_minus'] = False
def waterfall_chart(factors, contributions, base_value, current_value, title, save_path):
"""
factors: list, 因子名称列表,如 ["UV", "转化率", "客单价", "交叉项"]
contributions: list, 各因子的贡献量(绝对值变化量,非百分比),如 [+20000, -15000, +5000, -500]
base_value: float, 基准期总值
current_value: float, 当期总值
title: str, 图表标题
save_path: str, 保存路径
"""
labels = ["基准值"] + factors + ["当期值"]
values = [base_value] + contributions + [current_value]
# 计算瀑布图的底部位置和柱子高度
bottoms = [0]
heights = [base_value]
running = base_value
for c in contributions:
if c >= 0:
bottoms.append(running)
heights.append(c)
else:
bottoms.append(running + c)
heights.append(abs(c))
running += c
bottoms.append(0)
heights.append(current_value)
colors = ["#4472C4"] # 基准值:蓝色
for c in contributions:
colors.append("#2E7D32" if c >= 0 else "#C62828") # 正向绿,负向红
colors.append("#4472C4") # 当期值:蓝色
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(labels, heights, bottom=bottoms, color=colors, width=0.6, edgecolor='white')
# 在柱子上标注数值
for i, (bar, val) in enumerate(zip(bars, values)):
if i == 0 or i == len(values) - 1:
text = f"{val:,.0f}"
y_pos = bar.get_y() + bar.get_height() + base_value * 0.01
else:
text = f"{'+' if val >= 0 else ''}{val:,.0f}"
y_pos = bar.get_y() + bar.get_height() + base_value * 0.01
ax.text(bar.get_x() + bar.get_width()/2, y_pos, text,
ha='center', va='bottom', fontsize=10, fontweight='bold')
# 添加连接线
for i in range(len(bars) - 1):
x1 = bars[i].get_x() + bars[i].get_width()
x2 = bars[i+1].get_x()
y = bars[i].get_y() + bars[i].get_height() if i == 0 else bottoms[i] + heights[i]
ax.plot([x1, x2], [y, y], color='gray', linewidth=0.8, linestyle='--')
ax.set_title(title, fontsize=14, fontweight='bold', pad=15)
ax.set_ylabel("指标值")
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.savefig(save_path, dpi=150, bbox_inches='tight')
plt.close()
Using in the report: Embed the generated waterfall chart image into the diagnostic report (if it is an HTML report, embed it directly; if it is a Markdown report, reference the image path).
2.5 Outputs of factor decomposition
After this step is finished, you should be able to answer:
- "In which business link did the change mainly occur?" (e.g., the decline in conversion rate is the main cause, contributing 65%)
- "How much did each factor contribute?" (intuitively presented by the waterfall chart)
This conclusion directly determines the direction of Step 3—The dimensional attribution in Step 3 should prioritize the factor with the largest contribution, rather than blindly scanning the overall metric.
Step 3: Dimensional attribution (localization—on which dimensions the problem is concentrated)
Now that you know which link had the problem (Step 2), you need to locate "where the problem in this link is concentrated."
If Step 2 identified the main factor (e.g., conversion rate), this step performs dimensional attribution and drill-downtargeting that factor. If Step 2 is not applicable (the metric has no decomposition formula), then perform dimensional attribution directly on the overall metric.
3.1 Horizontal scanning: multi-dimensional parallel analysis
Select attribution dimensions
Query the available dimensions of the metric (or the main factor metric):
curl -H "X-API-Key: $CAN_API_KEY" "https://gateway.can.aloudata.com/api/metrics/{metricName}/dimensions"
Select 3-5 dimensions from the available dimensions that are most likely to affect fluctuations in business terms:
- User specified → prioritize the user's
- Not specified → prioritize business entity dimensions such as channel, region, product line, and brand
- Avoid dimensions with overly fine granularity (such as SKU), unless requested by the user
Query the change amount for each dimension
{
"metrics": ["{指标}", "{指标}__sameperiod__mom__value", "{指标}__sameperiod__mom__growthvalue"],
"dimensions": ["{维度名}"],
"timeConstraint": "DateTrunc(['metric_time'], \"MONTH\") = DATEADD(DateTrunc(NOW(), \"MONTH\"), -1, \"MONTH\")",
"orders": [{"{指标}__sameperiod__mom__growthvalue": "asc"}]
}
Note: The {指标} here should be the metric corresponding to the main factor found in Step 2 (such as buyer_cnt and visitor_cnt corresponding to conversion rate), and is not necessarily the overall metric the user initially asked about.
Calculate contribution
维度值变化量 = 当期值 - 基准值
总变化量 = Σ 所有维度值的变化量(应等于 Step 1 的总体变化量,作为校验)
贡献度 = 维度值变化量 / |总变化量| × 100%
The denominator usesabsolute value, positive contribution = driving growth, negative contribution = dragging down.
Highlight the main contributing factors
After calculating the contribution, mark the main contributors according to the following rules so that key findings are visible at a glance:
| Contribution (absolute value) | Marker | Meaning |
|---|---|---|
| ≥ 30% | 🔴 Main contributor | Must be analyzed in depth, as the drill-down target |
| 10% ~ 30% | 🟡 Secondary contributor | Worth attention, optional drill-down |
| < 10% | No marker | Small impact, generally no drill-down needed |
Evaluate the explanatory power of each dimension
- Concentration: Do a few dimension values contribute most of the change? (e.g., a certain channel contributes 70% of the decline) → strong dimensional explanatory power
- Business interpretability: Does the data finding make sense in business terms?
If the explanatory power of all dimensions is very weak (changes evenly distributed, no dimension value marked with 🔴), it suggests that this may not be a structural change, but rather holistic factors at play → look for explanations in Step 4 external events.
3.2 Vertical drill-down: go deeper layer by layer
When a certain dimension value contributes a significant amount of change, ask "within this dimension value, which sub-dimension caused it?"
Determine the drill-down path
Dimensions from coarse to fine:
一级渠道 → 二级渠道 → 地区 → 城市
品类大类 → 品类中类 → 品牌
Execute drill-down
For the dimension value with the largest contribution (top 1-2), add filters to constrain it, then perform attribution on the next-level dimension:
{
"metrics": ["{指标}", "{指标}__sameperiod__mom__value", "{指标}__sameperiod__mom__growthvalue"],
"dimensions": ["{下一层维度}"],
"filters": ["[{上层维度}]= \"{贡献最大的值}\""],
"timeConstraint": "..."
}
Drill-down termination conditions
- A sufficiently specific root cause has been found
- Changes are evenly distributed at the current level, with no concentration point
- The number of levels reaches 3-4
- The data volume is too small to be statistically meaningful
3.3 Output of dimension attribution
After this step, you should be able to answer:
- "Which dimension is the change in the problem factor mainly concentrated in?"
- "Specifically, which dimension value contributes the most?"
- "What is the root cause path after drill-down?"
Combined with the factor decomposition in Step 2, you should now have a complete causal chain, for example:
"GMV down 10% → main cause is conversion rate decline (contributes 65%) → conversion rate decline is concentrated in the Retail channel (contributes 70%) → further drill-down finds the largest decline in East China"
Step 4: External event correlation (find the cause—why is this happening)
Internal data tells you "what changed" and "where it changed", but the root cause is often external—weather, holidays, competitors, policies, etc. This step seeks external explanations for the data findings above.
4.1 Determine whether external correlation is needed
The following signals indicate that external factors need attention:
- Dimension attribution has no obvious concentration point: changes are evenly distributed, indicating a "holistic" factor
- Changes do not match seasonal patterns: e.g., air conditioner sales反而下降 in summer
- The magnitude of change is unusually large: beyond normal fluctuation, usually with an external trigger
- Users proactively mention external factors
In fact, even if dimension attribution has an obvious concentration point, it is still recommended to search for external events as supporting evidence—"Retail channel conversion rate decline" is a fact, but "why did Retail conversion rate decline" may require external information to answer.
4.2 External event search
Based on the business domain and the fluctuation time period, search for relevant external events:
| External factors | Search keyword examples | Typical impact patterns |
|---|---|---|
| Weather/natural disasters | "{region} {month} weather extreme rainstorm high temperature" | Affects offline foot traffic and logistics delivery |
| Holidays/major promotions | "{month} holidays promotional festivals Double 11 618" | Pre-promotion buildup - surge - decline cycle |
| Competitor actions | "{industry} competitors promotions price cuts new product launches" | Price wars cause changes in conversion rate/average order value |
| Industry policies | "{industry} policies regulations supervision new rules" | Compliance costs rise, categories restricted |
| Macroeconomy | "Consumer Confidence Index {Month} CPI Employment" | Overall change in consumption willingness |
| Platform rules | "{Platform name} algorithm traffic rules search ranking" | Changes in traffic allocation cause UV fluctuations |
Use the WebSearch tool to search (if available), or prompt the user to confirm known external events.
4.3 Event and data alignment
After identifying candidate external events, verify their consistency with the data findings:
Time alignment: Does the event occurrence time match the metric change time? (The event should precede or coincide with the change)
Spatial alignment: For regional events (such as heavy rain in a certain area), is the data for that region actually anomalous? Verify using the dimensional attribution results from Step 3.
Direction alignment: Is the expected direction of the event's impact consistent with the actual change? (Heavy rain → offline foot traffic decreases → offline channels did indeed decline)
Magnitude alignment: Is the scope of the event's impact sufficient to explain the magnitude of the change?
4.4 Output of external correlation
- "What external events may have affected the metrics?"
- "Are these external events consistent with the data findings?"
- "Which are certain conclusions supported by data, and which are speculations based on external information?"
Step 5: Comprehensive diagnostic conclusion
Summarize all findings to form a complete attribution report.
5.1 Report structure
# 指标波动归因诊断报告
## 1. 波动概况
- **分析指标**:{指标名称}
- **分析时段**:{当期} vs {基准期}
- **当期值**:{值} | **基准值**:{值}
- **变化量**:{±变化量}({变化率}%)
- **趋势判断**:{突发异常 / 持续趋势 / 季节性波动}
## 2. 归因发现
### 2.1 因子拆解(哪个环节出了问题)
**瀑布图**:(嵌入 Step 2 生成的瀑布图,直观展示各因子正负贡献)

| 因子 | 当期值 | 基准值 | 因子变化率 | 对总量贡献 | 贡献度 |
|------|-------|-------|----------|----------|-------|
| **{因子A}** 🔴 | xxx | xxx | {±X.X%} | {±xxx} | **{XX%}** |
| {因子B} | xxx | xxx | {±X.X%} | {±xxx} | {XX%} |
| {因子C} | xxx | xxx | {±X.X%} | {±xxx} | {XX%} |
→ 主要问题环节:**{因子A}**(贡献了 XX% 的变化)
### 2.2 维度归因(问题集中在哪里)
针对主因子 **{因子A}** 做维度归因,定位问题集中在哪里。
**Highlight 规则**:贡献度 ≥ 30% 的维度值标记为 🔴 主要贡献者,10%-30% 标记为 🟡 次要贡献者。
| 维度 | 维度值 | 当期值 | 基准值 | 变化量 | 贡献度 | 标记 |
|-----|-------|-------|-------|-------|-------|------|
| {维度1} | {值A} | xxx | xxx | {±xxx} | **{XX%}** | 🔴 主因 |
| {维度1} | {值B} | xxx | xxx | {±xxx} | {XX%} | 🟡 次因 |
| {维度1} | {值C} | xxx | xxx | {±xxx} | {XX%} | |
**下钻路径**:🔴 {维度1值A} → 🔴 {维度2值X} → 🔴 {维度3值Y},贡献了总变化的 XX%
### 2.3 外部事件(为什么会这样)
| 事件 | 发生时间 | 影响范围 | 与数据的一致性 |
|-----|---------|---------|-------------|
| {事件1} | {时间} | {范围} | {高/中/低} |
## 3. 归因结论
综合以上分析,本次{指标名}的{变化方向}主要由以下因素导致:
1. **主因**:{一句话说清核心原因,串联因子→维度→外部事件}
- 数据支撑:{因子拆解和维度归因的关键数字}
- 外部佐证:{相关外部事件,如有}
2. **次因**:{第二重要的原因}
- 数据支撑:...
3. **其他因素**:{其他较小的影响因素}
## 4. 建议关注
- {基于归因结论给出的可操作建议}
- {需要持续监控的指标或维度}
5.2 Report writing principles
Conclusion-driven, data-supported: State the conclusion first, then provide the evidence. Readers care most about "why it changed" and "what to do", not the analysis process.
Distinguish certainty: Directly proven by data ("data shows the conversion rate decline contributed 65%") vs. speculation based on external information ("speculated to be related to competitor promotions").
Provide a complete causal chain: The most valuable attribution is not a single-point finding, but a chain linking Step 2→3→4:
"Sales decreased 12% month-over-month, mainly due to an 18% decline in conversion rate (contributing 65% of the total decline). The conversion rate decline was concentrated in the Retail channel (contributing 70%), and further drill-down found the largest drop in East China (contributing 45%). Speculated to be related to aggressive competitor promotional activities in the region during the same period."
General specifications
Query construction
All API queries must comply with all the iron rules and specifications of metric-query, with particular attention to:
- Relative time must use
NOW(), hardcoded dates are prohibited metricDefinitionsEach key inmetricsarraycurlUse heredoc to pass the JSON body to- Dimension values must strictly follow the original format returned by Gateway
Query efficiency
Attribution analysis usually requires multiple queries. To reduce the number of queries:
- Use the
__sameperiod__series to obtain the current value, baseline value, and change amount at once - Keep the timeConstraint consistent across multiple queries
- During dimensional attribution in Step 3, multiple dimensions can be queried at the same time (placed in separate queries)
Numerical calculation
- The denominator for contribution should use theabsolute valueof the total change, to avoid sign confusion caused by negative numbers
- The sum of the contribution of each dimension value should approximately equal 100%, as a check (deviations > 5% need investigation)
- When decomposing factors, if the baseline value is 0 → label "No data in the baseline period, unable to calculate rate of change"
- Percentage-type metrics (such as conversion rate): clearly distinguish between "percentage point change" and "rate of change"
Common error patterns
❌ Starting analysis without confirming the baseline: the user says "the metric dropped" but does not say what it is being compared with. Confirm the baseline first.
❌ Skipping factor decomposition and directly scanning dimensions: if the metric has a business formula, decompose it first so that subsequent dimension attribution has direction. Otherwise you only know "Retail declined" but not which part of Retail had the problem.
❌ Only doing factor decomposition without dimension attribution: knowing "the conversion rate decline is the main cause" is not enough; you must further pinpoint which channel and which region saw the conversion rate decline.
❌ Only looking at internal data without linking to external events: the data tells you "where it changed", but "why it changed" often requires external information to answer. Especially when the dimension attribution results are evenly distributed, you should look even harder for external factors.
❌ Using signed values as the denominator for contribution: when the total change is negative, the sign flips. The denominator must use absolute values.
❌ Ignoring cross terms in factor decomposition: when the factor rate of change is > 10%, the approximation error of the decomposition cannot be ignored. Use Shapley decomposition or at least report the cross terms.
❌ Drilling down too deep with insufficient data volume: each level of drill-down narrows the data range; when the data volume is too small, conclusions are unreliable.
❌ Confusing "percentage point change" and "rate of change": conversion rate drops from 5% to 4% → percentage point change -1pp, rate of change -20%.
❌ Treating data correlation as causation: dimension attribution discovers "correlation"; causal inference requires combining external events and business logic.
Analysis quality checklist
- ✅ The comparison baseline has been confirmed and is reasonable
- ✅ The overall change has been quantified (with specific numbers and percentages)
- ✅ Factor decomposition (if applicable): the sum of the contributions of each factor equals the total change
- ✅ Factor decomposition (if applicable): cross terms have been checked
- ✅ Dimension attribution: conducted around the main factor (rather than the total metric)
- ✅ Dimension attribution: the sum of the contribution of each dimension value approximately equals 100%
- ✅ Dimension attribution: drilled down on the dimension value with the largest contribution (at least one level attempted)
- ✅ External events: at least searched for external events in the relevant time period
- ✅ External events: aligned for consistency with the data findings
- ✅ The comprehensive conclusion connects the complete chain of factor → dimension → external event
- ✅ The conclusion distinguishes certain findings from speculative judgments
- ✅ Actionable business recommendations are provided
- ✅ Percentage conventions are consistent (percentage points vs rate of change)
- ✅ All queries comply with the metric-query iron rules
- ✅ Factor decomposition generated a waterfall chart (if applicable)
- ✅ In dimension attribution, the main contributors (≥30%) have been highlighted with 🔴