You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
5.3 KiB
113 lines
5.3 KiB
---
|
|
date: 2026-04-16
|
|
topic: "GroenLinks-PvdA Merger Dynamics in SVD Space"
|
|
status: validated
|
|
---
|
|
|
|
## Problem Statement
|
|
|
|
We need concrete, data-driven findings about the GroenLinks-PvdA merger for a blog post. Four questions:
|
|
1. How similar were GL and PvdA in SVD space before the merger?
|
|
2. How cohesive is the merged party compared to others?
|
|
3. When did GL and PvdA converge in SVD space?
|
|
4. Which parties shifted the most, and how do GL/PvdA compare?
|
|
|
|
## Constraints
|
|
|
|
- Investigation-only: query the database, report findings, no code changes
|
|
- Database: `data/motions.db` (DuckDB), SVD vectors in `svd_vectors` table
|
|
- Party affiliation: use `mp_votes.party` for historical labels (not `mp_metadata` which only tracks current party)
|
|
- SVD vectors are at MP level (`entity_type='mp'`); party centroids must be computed from MP vectors
|
|
- Cross-window scale differences require normalization (distances as fraction of avg inter-party distance)
|
|
|
|
## Approach
|
|
|
|
**Method**: Compute party centroids from MP-level SVD vectors, grouped by `mp_votes.party` for historical party labels. Normalize all distances as fractions of the average inter-party distance in each window to make cross-window comparisons meaningful.
|
|
|
|
**Data source**: `svd_vectors` table (MP vectors per window) joined with `mp_votes` (historical party labels per vote, majority party per MP per year).
|
|
|
|
**Key discovery**: `mp_metadata` only tracks current party — pre-merger GL and PvdA MPs who merged are now labeled "GroenLinks-PvdA". We must use `mp_votes.party` for historical accuracy.
|
|
|
|
## Architecture
|
|
|
|
N/A — this is a data investigation, not a system design.
|
|
|
|
## Components
|
|
|
|
### Finding 1: GL-PvdA Pre-Merger Similarity
|
|
|
|
GL and PvdA were already remarkably close in SVD space well before the merger:
|
|
|
|
| Year | GL↔PvdA Distance | As % of Avg Inter-Party Distance | Nearest Other Party | Distance to Nearest |
|
|
|------|------------------|----------------------------------|---------------------|---------------------|
|
|
| 2019 | 2.10 | 10.5% | PvdD | 9.6 |
|
|
| 2020 | 2.23 | 5.0% | CU | 28.7 |
|
|
| 2021 | 1.46 | 4.4% | FVD | 11.6 |
|
|
| 2022 | 1.16 | 2.8% | FVD | 6.5 |
|
|
|
|
The nearest non-PvdA party to GL was always 5-10x further away than PvdA itself. They converged over time — from 10.5% of average inter-party distance in 2019 down to 2.8% in 2022.
|
|
|
|
### Finding 2: Post-Merger Cohesion
|
|
|
|
| Year | GL-PvdA Spread | Avg Other Spread | Ratio | Cohesion Rank |
|
|
|------|---------------|-------------------|-------|---------------|
|
|
| 2023 | 1.50 | 19.95 | 0.08 | #1 most cohesive |
|
|
| 2024 | 14.05 | 18.47 | 0.76 | Mid-pack |
|
|
| 2025 | 28.09 | 18.09 | 1.55 | Below average |
|
|
| Current | 43.30 | 28.05 | 1.54 | Below average |
|
|
|
|
The merged party started as the most cohesive party in parliament (2023), but by 2025 its internal spread is 55% above average — the merger created a party that's internally more diverse than typical Dutch parties.
|
|
|
|
### Finding 3: Merger Convergence Timeline
|
|
|
|
| Window | GL↔PvdA Distance | Normalized Ratio |
|
|
|--------|------------------|------------------|
|
|
| 2019-Q3 | 0.98 | 25.5% |
|
|
| 2020-Q1 | 1.38 | 18.6% |
|
|
| 2021-Q1 | 1.58 | 19.3% |
|
|
| 2022-Q3 | 0.86 | 9.4% |
|
|
| 2023-Q1 | 0.58 | 7.1% |
|
|
| **2023-Q3** | **0.37** | **4.5%** |
|
|
| 2023-Q4 | 0.46 | 5.5% |
|
|
|
|
By Q3 2023 — just before the formal merger — GL and PvdA centroids were only 4.5% of the average inter-party distance apart. Essentially indistinguishable in voting pattern space.
|
|
|
|
### Finding 4: Large Positional Shifts
|
|
|
|
GL and PvdA were the most stable parties in parliament (normalized drift per year):
|
|
|
|
| Period | GL Drift | PvdA Drift | VVD Drift | D66 Drift | PVV Drift |
|
|
|--------|----------|------------|-----------|-----------|-----------|
|
|
| 2019→2020 | 14.5% | 16.6% | 140.2% | 145.6% | 121.9% |
|
|
| 2020→2021 | 21.8% | 25.8% | 115.8% | 82.2% | 207.3% |
|
|
| 2021→2022 | 11.6% | 10.8% | 70.8% | 91.2% | 51.9% |
|
|
| 2022→2023 | 54.5% | 23.3% | 109.7% | 177.3% | 222.1% |
|
|
|
|
While VVD and D66 moved 70-177% per year, GL and PvdA drifted only 10-25%. The merger partners were anchored in place while the rest of the landscape shifted.
|
|
|
|
## Data Flow
|
|
|
|
1. Query `svd_vectors` for MP vectors per window
|
|
2. Join with `mp_votes` to determine each MP's majority party in that year
|
|
3. Compute party centroids as mean of member vectors
|
|
4. Compute pairwise distances and normalize by average inter-party distance
|
|
5. Track convergence timeline using quarterly windows
|
|
|
|
## Error Handling
|
|
|
|
- Windows with insufficient MPs (<3 per party) are excluded from centroid calculations
|
|
- The `mp_votes.party` column uses multiple label variants ("GroenLinks", "GL", "GroenLinks-PvdA") — normalized in queries
|
|
- The 2023 transition year has mixed labels (some GL, some PvdA, some GL-PvdA) — handled by majority-vote assignment per MP
|
|
|
|
## Testing Strategy
|
|
|
|
N/A — data investigation. Key validation checks:
|
|
- Cross-reference MP counts with known parliament compositions
|
|
- Verify that GL + PvdA MP counts match expected seat counts per year
|
|
- Confirm that convergence timeline aligns with known political events (merger announcement Oct 2023)
|
|
|
|
## Open Questions
|
|
|
|
- Should we compute cosine similarity instead of Euclidean distance for cross-window normalization?
|
|
- The 2025 and current_parliament windows show very different absolute scales — should we normalize vectors before computing distances?
|
|
- The few remaining "GL" (8) and "PvdA" (5) labeled MPs in 2025 may be artifacts — should they be included in the GL-PvdA group? |