EDAgent / README.md
Kogann's picture
Update README.md
ea0982b verified
|
Raw
History Blame Contribute Delete
4.71 kB
---
title: EDAgent
emoji: πŸ“Š
colorFrom: blue
colorTo: indigo
sdk: gradio
app_file: app.py
pinned: false
short_description: A 1.5B agent that writes, runs and repairs its own EDA code
---
# πŸ“Š EDAgent
Point it at any Hugging Face dataset. It extracts the schema, writes pandas /
matplotlib analysis code, executes that code, repairs it from the traceback if it
crashes, and assembles a Markdown + PDF report with tables and plots.
Built on **Qwen2.5-Coder-1.5B-Instruct**, small enough to run on a free GPU.
Three **Quick Starters** are pre-generated and load instantly without touching the
model, so the app is usable even when a visitor's daily GPU quota is exhausted.
## Architecture
| Stage | Owner | What happens |
|---|---|---|
| 1. Load + normalize | Python | `load_dataset` with a raw-file fallback; quoted nulls converted to real `NaN`; index-like columns dropped |
| 2. Context card | Python | One line per column: dtype, null count, cardinality, range |
| 3. Code generation | **LLM** | Schema + instruction β†’ one fenced Python block |
| 4. Execution | Python | `exec` in an isolated namespace, stdout captured, plots collected |
| 5. Repair (Γ—1) | **LLM** | Cleaned traceback (offending line + message) β†’ corrected script |
| 6. Facts + tables | Python | `idxmax`, `describe`, `corr` β†’ Markdown tables |
| 7. Narrative | **LLM** | One sentence per pre-computed fact |
## Design note
The model owns two jobs: writing analysis code and repairing it. Everything else β€”
table rendering, plot placement, and every "which is highest" lookup β€” is computed
in Python and handed to the model as a stated fact.
This was arrived at empirically. A 1.5B model reliably produced correct *descriptions*
and unreliable *lookups*: it rotated group means against their labels, invented
correlation pairs from fragments of two real ones, and inverted orderings. Adding
rules to the prompt made compliance worse, not better β€” at six simultaneous
constraints it stopped writing prose and began transcribing the input's structure.
Every fix that worked removed responsibility from the model rather than adding
instruction to it.
`df.corr()` on mixed-type data is patched deterministically rather than left to the
repair loop: it failed on both test datasets, and the model fixed it correctly once
(`select_dtypes(...).corr()`) and incorrectly once (`dropna(subset=[...]).corr()`).
## Plot and table quality
Generated plotting code is wrapped rather than trusted. `seaborn.heatmap`,
`seaborn.histplot` and `plt.savefig` are patched around execution so that, on any
dataset:
- correlation heatmaps scale their canvas with the matrix and drop cell annotations
past 12 columns;
- long column names are abbreviated while keeping their suffixes;
- axes with more than 20 tick labels are thinned;
- heavily right-skewed distributions (prices, fares, incomes) are replotted on a log
axis;
- no axis or table ever shows scientific notation β€” `37,000,000`, not `3.7e+07`.
Near-perfect correlations (|r| β‰₯ 0.99) are separated into a **Redundant Columns**
section, since they are almost always duplicate encodings rather than findings.
## Known limitations
- The model is text-only and never sees the plots it generates; it is explicitly
prevented from describing them.
- `audit_numbers` flags numerals absent from the evidence. It detects fabrication,
not misinterpretation, and false-positives on derived values.
- The model occasionally embellishes a supplied fact. This is the residual failure
mode once every lookup has been moved into Python.
- Non-tabular, image and audio datasets are not supported.
- One repair attempt only. If it fails, the report is built from the data alone.
## Security
This Space executes LLM-generated Python. A static check blocks `subprocess`,
`socket`, `open()`, `eval`/`exec` and `os`/`sys` imports, but `exec` is not a
sandbox β€” treat the guard as a speed bump. **Do not add secrets to this Space's
settings.**
## Hardware
Built for **ZeroGPU**. The model is placed on `cuda` at module level and all GPU work
runs inside a `@spaces.GPU` function; the app also falls back to CPU so it boots
anywhere. One fresh report is about seven generation calls, roughly 60–90 s of GPU
time. Results are cached in memory, and the Quick Starters are served from disk, so
repeat views cost nothing.
## Repository layout
```
app.py the agent and the Gradio UI
requirements.txt
quickstarts/
titanic/ meta.json report.md code.py stdout.txt report.pdf plots/*.png
iris/ ...
housing/ ...
```
`quickstarts/` is generated by the companion Colab notebook. If it is absent, the
Quick Starter buttons fall back to a live run.