sgeboers 7df961ba83 feat(overton): address 7 critical gaps in Overton window analysis
U1: Temporal trajectory — quarterly granularity reveals immediate
electoral jump at 2024-Q1 (+0.180), peak at 2024-Q4 (0.648), reversion
to 0.334 by 2026-Q1.

U2: 2D extremity temporal — single-score masks divergence. Material
impact decreased (-0.146) while stylistic increased (+0.097).
Wilcoxon p=0.002 confirms systematic divergence.

U3: Systematic mechanism classification — 150 motions. Consensus
framing confirmed (24% high-CS vs 8% low-CS, p=0.014). Post-2024
high-CS dominated by procedural (32%), consensus (24%), targeted
restriction (17%).

U4: Causal timing — shift is electorally driven (after Nov 2023 PVV
election, before Jul 2024 Schoof cabinet). Rules out coalition
dynamics, gradual learning, European contagion.

U5: Left-wing response — barely changed (21.3%→20.2%, -1.1pp).
Centrist shift (d=+1.89) is 18.3x larger than left hardening
(d=-0.75). Volt is only left party that softened (+12.9pp).

U6: Success correlation — significant trend (p<0.001) but success
premium only +3.2%, ceiling effect at 96%+ limits practical meaning.

U7: Synthesis update — integrated all findings, updated verdict
to note electoral-cycle effect and 2026-Q1 reversion.
2026-05-26 23:33:13 +02:00
2026-05-04 22:05:06 +02:00

Stemwijzer

A Dutch parliamentary voting compass that lets you vote on real Tweede Kamer motions and see which parties match your positions.

Stemwijzer Explorer

What is Stemwijzer?

Stemwijzer ingests motions and voting records from the Dutch House of Representatives (Tweede Kamer), stores them in DuckDB, generates AI-powered explanations with an LLM, and presents a Streamlit UI where users can vote on real motions and explore party positions through SVD visualizations, trajectory analysis, and embedding-based similarity search.

Features

  • Voting Compass — Vote on real parliamentary motions and see which parties align with your choices
  • Explorer — Interactive SVD visualizations, party trajectories over time, motion browser, and semantic search
  • Analytics — SVD decomposition of voting patterns, UMAP projections, clustering, and drift analysis
  • LLM Enrichment — Automatic generation of layman-friendly motion explanations using QWEN via OpenRouter

Prerequisites

  • Python >= 3.13
  • uv for dependency management
  • (Optional) OPENROUTER_API_KEY for LLM enrichment

Quickstart

# Clone and enter the repository
git clone <your-gitea-url>/sgeboers/stemwijzer.git
cd stemwijzer

# Install dependencies
uv sync

# Run the Streamlit app
uv run streamlit run Home.py

# Run the data pipeline (fetch motions, compute embeddings, etc.)
uv run python pipeline/run_pipeline.py

# Run tests
uv run pytest tests/ -q

The app will be available at http://localhost:8501.

Project Structure

├── app.py              # Streamlit UI entrypoint
├── database.py         # DuckDB schema and queries
├── api_client.py       # Tweede Kamer OData API client
├── explorer.py         # Explorer page with SVD visualizations
├── pipeline/           # Data ingestion and analysis pipelines
├── analysis/           # SVD, clustering, trajectory, right-wing motion analysis
├── tests/              # pytest test suite
├── docs/               # Documentation, research, and plans
└── data/motions.db     # DuckDB database (~18 GB)

Documentation

  • ARCHITECTURE.md — Comprehensive architecture overview, tech stack, and contributor guidance
  • CODE_STYLE.md — Coding conventions, naming, typing, and testing standards
  • docs/solutions/ — Documented solutions to past bugs and best practices

Tech Stack

  • Language: Python 3.13+
  • Data: DuckDB via ibis-framework
  • UI: Streamlit + Plotly
  • ML/Analysis: scipy, scikit-learn, umap-learn
  • LLM: QWEN via OpenRouter (OpenAI-compatible)
  • Package Manager: uv

License

[Your license here]

S
Description
No description provided
Readme
28 MiB
Languages
HTML 96.7%
Python 3.2%