File size: 4,708 Bytes
279bb16 d69669a b24ae64 279bb16 b24ae64 279bb16 ad90647 b24ae64 36490c1 ea0982b b24ae64 36490c1 b24ae64 ea0982b b24ae64 ea0982b 36490c1 b24ae64 36490c1 b24ae64 ea0982b b24ae64 36490c1 b24ae64 ea0982b b24ae64 36490c1 b24ae64 36490c1 b24ae64 36490c1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | ---
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. |