Probabilità e istogrammi con Python: lanciamo una moneta

Lanciamo una moneta e verifichiamo il concetto di deviazione standard

Lanciamo una moneta: probabilità e istogrammi con Python

Come noto dalla teoria della probabilità, possiamo definire la Varianza di una variabile aleatoria x (o meglio della sua distribuzione), come:

\sigma^{2}_{x} =Varianza (X)=\frac{\sum _{x\in X}(x-\mu)^{2}}{\left|X \right|}

dove X è un certo insieme di valori, |X| è la dimensione dell’insieme dei valori e μ è la sua media.

Al di là dei formalismi, la varianza esprime quale percentuale di valori è vicina alla media. Se molti valori sono vicini alla media, la varianza sarà piccola. Se molti valori sono lontani dalla media, la varianza sarà grande. Se i valori sono tutti uguali, la varianza è zero.

Inoltre, la Deviazione Standard di un insieme di valori è la radice quadrata della varianza. Varianza e deviazione standard contengono quindi la stessa informazione. Tuttavia, la deviazione standard è di più semplice interpretazione in quanto essa è espressa nella stessa unità di misura dei dati. Così, usando la deviazione standard, si comprendono facilmente espressioni del tipo “l’altezza media dei maschi italiani è di 180cm con a una deviazione standard di 10cm”.

Un esempio di codifica in Python (che naturalmente possiede moduli ben più sofisticati a tale scopo), potrebbe essere:


def var(X):
    media=sum(X)/len(X)
    tot=0.0
    for x in X:
        tot+= (x-media)**2
    return tot/len(X)

def devStd(X):
    return var(X)**0.5

X=[1,2,3,4,5,6,7,8,9,10]
print ('Valori:\n',X,'\n Varianza= ',var(X),'\n Deviazione Standard= ',devStd(X))

La deviazione standard può quindi essere vista come il grado di sicurezza che possiamo avere sui calcoli effettuati dato un certo insieme di valori X.

Esperimento: lanciamo la moneta

Come piccolo esercizio per visualizzare il significato della deviazione standard, procederemo con questo esperimento: lanceremo una moneta N volte (numLanci) e calcoleremo la frequenza dell’evento Testa. Ripeteremo poi questo stesso esperimento per M volte (numProve). Al termine, calcoleremo media e deviazione standard della frequenza dell’evento Testa. Ci aspettiamo, che al crescere di numlanci la deviazione standard della frequenza delle teste diventi sempre più piccola. La media invece, chiaramente dovrebbe essere molto vicina a 0.5.

Grafici dei risultati dell’esperimento lanci della moneta

Ci limiteremo a riportare i grafici di 4 casi. Nel primo per 10 volte (numProve) lanciamo la moneta 10 volte (numLanci); nel secondo per 10 volte lanciamo la moneta 100 volte; nel terzo per 10.000 volte lanciamo la moneta 100 volte; nell’ultimo per 10.000 volte lanciamo la moneta 1.000 volte.

10 prove per 10 lanci
Istogramma 10 lanci per prova
100 lanci 10 prove
Istogramma 100 lanci per prova
Istogramma 100 lanci per prova
Istogramma 100 lanci per prova
Istogramma 1000 lanci per prova
Istogramma 1000 lanci per prova

E infine il codice Python per ottenere i grafici


import pylab
import random
import statistics
def flip(numLanci):
    teste=0
    for i in range(numLanci):
        if random.choice(('T','C'))=='T':
            teste+=1
    return teste/float(numLanci) #calcolo la frequenza di teste
        
def flipSim(numLanciPerProva,numProve):
    percTeste=[] #conterrà la frequenza di teste per ogni prova
    for i in range (numProve):
        percTeste.append(flip(numLanciPerProva))
    mean=sum(percTeste)/len(percTeste) #calcolo la media
    sd=statistics.stdev(percTeste) #e la deviazione standard
    return(percTeste,mean,sd)
def labelPlot(numLanci,numProve,mean,sd):
    #titolo del grafico
    pylab.title(str(numProve)+' prove di '+str(numLanci)+' lanci ciascuna')
    #etichetta asse x
    pylab.xlabel('Frequenza di Teste')
    #etichetta asse y
    pylab.ylabel('Numero di Prove')
    #scrivo del testo dentro il grafico ove l'argomento xy indica dove verrà posizionato, in percentuale, rispetto all'angolo inferiore sinistro
    pylab.annotate('Mean= '+str(round(mean,4))+'\nSD= '+str(round(sd,4)),\
                size='x-large',xycoords='axes fraction',xy=(0.05,0.8))
def makePlots(numLanci1,numLanci2,numProve):
    val1,mean1,sd1=flipSim(numLanci1,numProve)
    #traccio primo istogramma, i valori vengono divisi in intervalli da 20
    pylab.hist(val1,bins=20)
    #valori max e min dell'asse x automatici
    xmin,xmax=pylab.xlim()
    #scrivo le etichette
    labelPlot(numLanci1,numProve,mean1,sd1)
    pylab.figure()
    val2,mean2,sd2=flipSim(numLanci2,numProve)
    pylab.hist(val2,bins=20)
    pylab.xlim(xmin,xmax)
    labelPlot(numLanci2,numProve,mean2,sd2)
makePlots(100,1000,10000)
    

Foto di Eduardo Soares

servizialleimprese
Avatar photo
Informazioni su TG Team 129 Articoli
We are the TG magazine editorial team, a unique pool of copywriters and engineers to get you through technologies and their impact on your business. Need our expertise for an article or white paper?