Uitleg berekening partijvergelijking

Methode: Pearson-correlatie - min. 10 overlappende stellingen

Op deze pagina leggen we uit hoe de percentages tot stand komen. We gebruiken de Pearson-correlatie om te meten hoe sterk jouw antwoorden inhoudelijk gelijklopen met de standpunten van een partij. Zo voorkomen we dat partijen met vooral gematigde posities automatisch voordeel hebben.

In het kort

Stap-voor-stap formule

1) Verzamel de paren (u_i, p_i) voor alle stellingen met overlap
   - u_i = jouw antwoord (∈ { -2, -1, +1, +2 })
   - p_i = partijpositie (∈ { -2, -1, +1, +2 })

2) Centreer beide reeksen (haal het gemiddelde eraf):
   u_mean = mean(u), p_mean = mean(p)

3) Bereken:
   cov = Σ (u_i - u_mean)(p_i - p_mean)
   su2 = Σ (u_i - u_mean)²
   sp2 = Σ (p_i - p_mean)²
   r   = cov / √(su2 · sp2)     (veiligheid: als su2 of sp2 ≈ 0 ⇒ r = 0)

4) Zet r om naar 0..100%:
   percentage = round(50 + 50 × r)

5) Minimum overlap:
   als #overlap < 10 ⇒ percentage = 0
      

PHP-implementatie

Onderstaande code is precies de methode die we gebruiken.


<?php
// Minimaal aantal overlappende stellingen per partij
define('RESULTS_MIN_OVERLAP', 10);

function pearson(array $u, array $p): float {
    $n = count($u);
    if ($n < 3) return 0.0; // minimaal wat variatie nodig

    $meanU = array_sum($u) / $n;
    $meanP = array_sum($p) / $n;

    $cov = 0.0; $uu = 0.0; $pp = 0.0;
    for ($i = 0; $i < $n; $i++) {
        $du = $u[$i] - $meanU;
        $dp = $p[$i] - $meanP;
        $cov += $du * $dp;
        $uu  += $du * $du;
        $pp  += $dp * $dp;
    }

    if ($uu <= 1e-9 || $pp <= 1e-9) return 0.0; // geen variatie ? r = 0
    return $cov / sqrt($uu * $pp);               // r ? [-1, 1]
}

// $positions: [partij => [qid => -2..+2]], $userAnswers: [qid => -2..+2]
$results          = [];
$noOpinionCounts  = [];

foreach ($positions as $party => $standpunten) {
    $u = []; // user vector
    $p = []; // partij vector
    $noOpinionCount = 0;

    if (is_array($userAnswers)) {
        foreach ($userAnswers as $qid => $userValRaw) {
            $userVal = (int)$userValRaw;
            if ($userVal === 0) continue; // skip gebruiker neutraal

            $key = (string)$qid;
            $partyVal = $standpunten[$key] ?? null;

            // skip partij neutraal/afwezig (0 of null)
            if ($partyVal === null || (int)$partyVal === 0) {
                $noOpinionCount++;
                continue;
            }

            $u[] = $userVal;
            $p[] = (int)$partyVal;
        }
    }

    // correlatie ? 0..100%
    $r = pearson($u, $p);
    $percent = (int) round(50 + 50 * $r);

    // Vereis voldoende overlap
    if (count($u) < RESULTS_MIN_OVERLAP) {
        $percent = 0;
    }

    $results[$party]         = max(0, min(100, $percent));
    $noOpinionCounts[$party] = $noOpinionCount;
}
?>
    
Historische methode (ter vergelijking)

Voorheen gebruikten we een lineaire afstandsmethode per stelling. Deze kan partijen met veel gematigde posities bevoordelen. Daarom zijn we overgestapt op correlatie. (Code niet langer in gebruik.)