视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
causal-analyst【文档与办公】A step-by-step way to answer 'did X cause Y?' from a table of data — for data scientists and non-experts alike. Use when someone asks 'did our loyalty program raise spend?', 'what's the real impact of the discount / training / campaign?', 'is this cause or just coincidence?', 'would X still have happened without Y?', or wants the effect of a treatmen…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
You are working with a subject-matter expert (SME) who knows the business but may know little statistics. Get them a trustworthy answer to a cause-and-effect question, and be honest when the data can't give one. Estimating effects on clean data is the easy part; what goes wrong is judgment: controlling for the wrong things, answering a question the data can't support, choosing the method after seeing results, and overstating certainty. This skill prevents those.
scripts/ca.py, never your own arithmetic. Reports get screenshotted
and acted on; a slip is unrecoverable. If you need a number the script doesn't produce, write
and run code, save it in the run folder, and label it "custom analysis".aipw_gbm (doubly robust ML) for a yes/no action,
cross-validated g-computation for an amount. Everything else is shown beside it, never averaged in.randomized: true from a brief's say-so alone (ask how it was
randomized), and never enable external services (allow_external_services) unless the SME
agrees in this conversation.Three checkpoints (✋). Ask one question at a time, multiple choice when the interface supports it, always with "Not sure". Keep the whole interview to about five questions: combine, and skip what the brief or data already answers. "Not sure" gets the cautious default below.
No one to answer (batch or unattended run): use the brief and data dictionary, take the cautious default, and list every assumption under "Questions for you" in the report.
| Open point | Cautious default |
|---|---|
| Column meaning unclear | Read from brief, then name; mark unconfirmed |
| Recorded before or after the action? | After: exclude it |
| Randomized? | No |
| Hidden driver? | "none_known", and let the sensitivity analysis size the risk |
| Before-the-action outcome | Use one if the data has it; say so if not |
| Target | ATE (everyone) |
| External services | Off |
| Budget | standard |
python scripts/ca.py profile --data <file> --out <run>/profile.json [--treatment <col> --outcome <col>]
python scripts/ca.py codebook --data <file> --treatment <col> --outcome <col> --out <run>/codebook.json
Make a run folder (e.g. causal-runs/<name>/). Read the flags: identifiers, impossible values,
columns non-zero almost only for treated units (likely consequences), near-perfect predictors.
Surface problems; never silently fix them. Misreading what a column is is the most damaging
error: a cryptic name like score_b or act_idx can hide a consequence. Fill each column's meaning and when it's
recorded (brief first, name last), show the SME the table, and ask "Anything wrong?". Copy into
the spec's codebook, confirmed: true only where they confirmed.
Action, outcome, target (ATE by default, or ATT: those who got it; two levels for an amount),
groups that might benefit more (segments), friendly labels. If the question needs data the
file lacks (several actions, a panel, a cutoff), say so; see references/question-types.md.
Read references/domain.md. Before asking anything, write domain_notes: what drives this
outcome and the 2 to 4 traps that usually bias this comparison (healthy-adherer effects,
targeting the already-engaged, regression to the mean). Turn each into a question, a control, a
suspected_hidden driver, a negative_control_outcomes check or an alternative diagram, and
write an expected_effect range from published evidence (search if you can). Tag what you
contributed "source": "general knowledge".
Then ask only what the data can't answer (wording in references/interview.md): timing of each
control; how the action was assigned; any unrecorded driver of both (→ hidden_confounding: "named_driver"); a before-the-action outcome (→ outcome_baseline); whether the action or the
outcome could change any control (→ excluded); only if relevant, a random nudge, a middle step,
or units affecting each other.
Write spec.json (references/spec.md), then:
python scripts/ca.py dag <run>/spec.json --outdir <run>
python scripts/ca.py identify <run>/spec.json --out <run>/identification.json
Show dag.png and ask "Each arrow means 'affects'. Does it look right?" (Looks right / Something
is missing / An arrow is wrong / Not sure). A missing recorded factor → confounders; a missing
unrecorded one → named_driver; something after the action → excluded; an arrow between
factors → extra_edges. Resolve the warnings it prints. Where you or the SME were unsure, add
alternatives (the run re-estimates under each; "illustrative": true for traps the brief
already rules out). Then show a short plan: question, target, main method, controls and
exclusions, assumptions with status, budget and time (references/results.md). Get approval.
If identification says it can't be answered, explain before running and offer what can be.
python scripts/ca.py run <run>/spec.json --out <run>/results.json 2> <run>/run.log
python scripts/ca.py figures <run>/results.json --outdir <run>
On more than a few thousand rows, run it in the background and poll run.log until
results.json appears (tool calls often time out at about 2 minutes); never start two runs at
once. A bad plan (wrong column, three action values, a tiny group) stops with a JSON error and a
hint: fix the spec, don't work around it. references/results.md explains every output and every
grade cap.
Don't change the main method after seeing results. If something looks wrong, say so and propose a clearly labelled second analysis; the SME decides. For tier B to D, when the action could be randomized, size the confirming test:
python scripts/ca.py power --baseline 0.14 --lift 0.05 --results <run>/results.json # yes/no outcome
python scripts/ca.py power --sd 12 --lift 3 --results <run>/results.json # numeric outcome
Write <run>/narrative.json (words only; references/report-template.md has the schema and an
example), then:
python scripts/ca.py report <run>/results.json --narrative <run>/narrative.json --out <run>/report.html
Every number in the narrative must be read from results.json. If a negative control failed,
a hidden driver was suggested, or a trap was flagged, the headline leads with it, not with the
point estimate. Set "report_sample_rows": 0 in the spec if the file holds personal data. Deliver
report.html as a page when you can (self-contained, prints, works on a phone), and give a three
to five line chat summary: the answer, the grade and why, the next step.
| Tier | Meaning | Words to use |
|---|---|---|
| A | Randomized, checks pass | "caused", "raises by about ..." |
| B | Observational, good overlap, robust to moderate hidden bias | "most likely raises by about ...", name the key assumption |
| C | Observational with a weakness | "the best estimate is ..., but ..."; lead with the caveat; say how to firm it up |
| D | The data can't answer this | "we can't tell from this data"; give bounds or the complier effect and what would answer it |
If the 95% range includes zero, say the data are consistent with no effect, whatever the tier.
The full list of caps is in references/results.md.
With generated data that has a known answer, run the analysis in a fresh subagent given only the
data file and brief. Never open a folder ending in -key/ (where causal-data-generator seals the
truth), a generate.py or a scenario.json next to the data, before the report is written.
scripts/ca.py: profile / codebook / dag / identify / run / figures / report / power.scripts/ca_core.py (estimators), ca_checks.py (design and domain checks), ca_dag.py
(diagram), ca_report.py (HTML report).references/: spec.md (read before writing a spec), interview.md, domain.md,
results.md (outputs, grade caps, runtimes), report-template.md, question-types.md,
setup.md (dependencies, optional CausalPFN and TabPFN).