Corsi on-line

Proiezioni di voto con PHP

Attenzione, non voglio parlare di politica… non in senso stretto. Quello che vorrei affrontare con questo post è il problema (puramente statistico) della bontà delle famigerate proiezioni, ovvero la previsione del risultato elettorale a scrutinio aperto (cioè prima che lo scrutinio sia terminato).

Quando il commentatore, dopo appena 10 seggi scrutinati se non addirittura prima, dice “Pinco ha il 30% e Pallo il 60%” ci sta raccontando una balla (e qui qualche statistico puro mi darà ragione), in quanto la verità è che “con molta probabilità Pinco avrà tra il 12 ed il 56% mentre Pallo tra il 34 ed l’80%” che, come si capisce, è molto diverso dalla precedente affermazione.

Per semplice divertimento ho così deciso di farmi da solo uno scriptino in PHP per fare questo tipo di calcoli… in modo più sincero, però! Ovviamente (e qui qualche statistico puro inorridirà) per semplificaremi la vita ho introdotto delle approssimazioni non proprio “corrette” quando la percentuale si avvicina troppo allo zero o al 100%, ma considerando che non ho l’ambizione di dirigire il TG4 direi che può andar bene lo stesso:

<?php
if(isset($_POST['invia'])){
 $percen=$_POST['percento']+0;//percentuale rilevata sul campione
 $numer=(int)$_POST['campione']+0;//numerosità del campione
 $z_s= $_POST['grado']+0;//valore di z per grado di sicurezza
 //arrotomdo la percentuale impostata e la porto a valore tra 0 e 1
 $percen=round($percen, 1)/100;//riporto es. 33.555487 a 0.336
 //verifico i post (si può fare di meglio con filter_var ecc...)
 if($percen <=0 || $percen >=1 || $numer <=1 || $z_s==0){
  echo "hai fatto un errore nell'immissione dei dati";
  echo "<meta http-equiv='Refresh' content='3; URL=".htmlspecialchars($_SERVER['PHP_SELF'])."'>";
 }else{//i dati sono giusti
  //potevo trasmetterlo, ma mi ricavo il grado di sicurezza
  if($z_s==1.65){
   $sicuro="90%";
  }elseif($z_s==1.96){
   $sicuro="95%";
  }elseif($z_s==2.58){
   $sicuro="99%";
  }//fine if grado di sicurezza
  //suddivido la formula in più parti (comuni tra min e max)
  //usando qualche parentesi in più per evidenziare meglio il calcolo
  $uno=$numer/($numer+($z_s*$z_s));
  $due=$percen+($z_s*$z_s)/(2*$numer);
  $tre=($percen*(1-$percen)/$numer)+ (($z_s^2)/(4*$numer*$numer));
  $tre=sqrt($tre);//estraggo la radice quadrata
  $min=round($uno*($due-$z_s*$tre), 3)*100;//calcolo limite inferiore arrotondando al secondo decimale e riporto a 100
  $max=round($uno*($due+$z_s*$tre), 3)*100;//calcolo limite superiore
  //aggiusto gli estremi in quanto minimo non può essere minore di zero
  // e massimo maggiore di cento
  if($min<0){$min=0;}
  if($max>100){$max=100;}
  //non sarebbe esattamente così, ma in larga approssimazione può andare
  $per=$percen*100;
  echo "se da un campione di $numer ricavo una percentuale pari a $per%<br>";
  echo "con un grado di sicurezza del $sicuro posso stimare che la vera percentuale sarà compresa<br>";
  echo "tra un minimo del <b>$min</b>% e un massimo del <b>$max</b>%";
 }//fine if-else verifica input
}//fine if submit
?>
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>" method="post">
<table width="100%"  border="0" cellspacing="2" cellpadding="0">
  <tr>
    <td>numerosit&aacute; campione</td>
    <td><input name="campione" type="text" size="5"></td>
    <td>(numero intero > 1)</td>
  </tr>
  <tr>
    <td>percentuale rilevata sul campione</td>
    <td><input name="percento" type="text" size="4"></td>
    <td>(0 < numero float < 100 - es. 33.4)</td>
  </tr>
  <tr>
    <td>grado di sicurezza</td>
    <td><select name="grado">
    <option value="1.65">90%</option>
    <option value="1.96">95%</option>
    <option value="2.58">99%</option>
    </select></td>
    <td>&nbsp;</td>
  </tr>
</table>
<input type="submit" name="invia" value="invia">
</form>

E’ evidente che lo script non tiene conto del numero complessivo degli elettori (che è considerato infinito).
Infatti anche inserendo il numero finale di elettori il mio script restituirà sempre e comunque un intervallo.
Da notare due cose:

  1. comunque, e questo è intuitivo, al crescere del numero la forbice si stringe (teoricamente i due limiti si avvicinano sempre di più al vero valore). Facciamo un esempio: se pinco ha ottenuto il 30% di voti dopo lo scrutinio di 1.000 schede la forbice sarà tra 23 e 38% mentre dopo lo scrutinio di 1.000.000 schede la forbice sarà tra 29.9 e 30.1%
    (a parità di grado di sicurezza);
  2. meno intuitivo, per i non statistici, è il fattore che ho indicato con “grado di sicurezza”.
    Lo statistico onesto dichiara sempre con quale grado di sicurezza (probabilità) fa una data previsione e, come si nota, più “voglio essere sicuro” e più la forbice si allarga.

Concludo spezzando una lancia a favore della statistica, parafrasando un detto di trilussa.
Se siamo in due e io mangio due polli e Caio nemmeno uno, i media diranno “la statistica dice che Gianni e Caio hanno mangiato un pollo a testa“. Falso, lo statistico dirà “Gianni e Caio hanno magiato (mediamente) un pollo ‘più o meno uno’ a testa“, le due affermazioni – pur simili – sono completamente diverse.

Se lo script vi è piacuto, conservatelo, fra tre anni dovrebbe servire di nuovo…

Post correlati
I più letti del mese
Tematiche