Skip to content

Teaching Notebooks

Ten step-by-step breakdowns — one per technique family, plus a data/eval foundation and a cross-technique synthesis. Each notebook builds the method from primitives on the real catalog and runs its evaluation live, so you see not just how a technique works but how it scores (ADR-0014).

These pages show real, executed outputs

Every notebook here is rendered from a pre-executed .ipynb — the tables, plots, rankings, and (for notebook 08) the live local-LLM responses are the actual outputs from running against the 11,073-course catalog. The versioned source is the notebooks/*.py jupytext percent script; these executed notebooks are the published render artifact (ADR-0015).

The sequence

Notebook 00 is the foundation — every technique notebook assumes it. After that, the numbered notebooks are independent; read the one whose technique interests you.

# Notebook What it builds
00 Data & Eval foundation The cleaned catalog and the three-lens evaluation harness — the shared plumbing every other notebook uses.
01 Lexical TF-IDF + cosine and Okapi BM25 from the term-document matrix up. The honest baseline.
02 Topic models LSA, NMF, and LDA — compressing the term space to latent topics.
03 Semantic vectors SBERT sentence embeddings (MiniLM, MPNet) — the winner on free text.
04 Retrieve → rerank → MMR A cross-encoder reranker over SBERT candidates, with an MMR diversity knob.
05 Metadata fusion Fusing one-hot facets with text — and why it hurts the cross-listing target.
06 Course graph (PPR) Personalized PageRank on a held-out edge split — the leak-safe graph.
07 Clustering & 2-D map KMeans / Ward / HDBSCAN over the embeddings as a diagnostic, not a ranker.
08 LLM enrichment & rerank Local qwen3:8b for tags, zero-shot rerank, and explanations — where the LLM loses and where it wins.
09 Leaderboard synthesis All techniques side by side — the cross-technique payoff.

Running them yourself

The notebooks live in notebooks/ as jupytext py:percent scripts. To run locally:

pip install -e ".[notebooks,semantic]"
jupytext --to ipynb notebooks/01_lexical.py
jupyter lab notebooks/01_lexical.ipynb

Notebook 08 additionally wants a local Ollama daemon with qwen3:8b pulled — but it degrades gracefully to its cache when Ollama is absent. See the Runbook for the full install matrix.