| English | Português |
Can we tell whether a molecule is toxic just from its structure? This project builds and honestly evaluates machine-learning models that predict the results of 12 toxicity assays for about 7,800 chemicals. It also includes an app that profiles any molecule you paste in.
Data: Tox21 (US EPA, NIH, FDA) via MoleculeNet. It covers 7 nuclear-receptor assays (hormone disruption) and 5 stress-response assays (DNA damage, oxidative stress, mitochondrial damage). Each result is active or inactive. Classes are imbalanced (3–16% active) and some labels are missing.
Plain-language summary: open the live dashboard (source), a one-page overview for non-technical readers in English and Portuguese.
More projects: Why clinical trials stop early · Portuguese education data · Spotting students at risk in online courses
Random splits flatter the model. Under a scaffold split, where test molecules have ring systems never seen in training, mean ROC-AUC is 0.79, compared with 0.83 under a random split. The scaffold split is the honest estimate for new chemistry.

Trust depends on similarity. ROC-AUC is 0.86 for test molecules similar to the training data and 0.72 for the least familiar third, so every prediction should come with a similarity score.

Paste a SMILES string, or pick an example such as bisphenol A, triclosan or benzo[a]pyrene. The app shows:
streamlit run app/app.py
src/featurize.py downloads Tox21; cleans molecules; computes Morgan fingerprints, RDKit descriptors, scaffolds and splits
src/train_models.py trains the final per-assay random forests used by the app
src/style.py shared chart style
notebooks/01_explore_tox21.ipynb assays, imbalance, assay correlations, structure–activity patterns, scaffolds
notebooks/02_predict_toxicity.ipynb random vs scaffold split, model comparison, applicability domain, toxic fragments, enrichment
app/app.py Streamlit toxicity profiler
figures/ exported charts
toxicity-at-a-glance.html plain-language dashboard
pip install -r requirements.txt
python src/featurize.py # ~1 minute
python src/train_models.py # a few minutes, only needed for the app
jupyter notebook notebooks/
Educational project. The predictions are not a safety assessment.