SVILUPPO DI UNA CLASSE STATISTICA IN AMBIENTE JAVA
POTOK MARCO
Università degli Studi di Trieste
A.A. 2011/2012
SVILUPPO DI UNA CLASSE STATISTICA IN AMBIENTE JAVA
ANALISI ED ESEMPI D'UTILIZZO
Potok Marco
➢ IDEA
Creare un programma Java in grado di risolvere problemi statistici assegnati in classe e proposti nei temi
d'esame.
➢ COME
In primis è stata scritta una classe Stat dove sono stati implementati vari metodi con le principali
funzioni per la risoluzione dei problemi di statistica. In seguito la classe Stat è stata opportunamente
usata per risolvere 5 esercizi (2 compiti per casa e 3 temi d'esame). Sono state quindi create 5 classi con
un metodo main per stampare a video i risultati. Vedremo in dettaglio ogni risoluzione.
➢ LA CLASSE STAT
Ora vedremo in dettaglio la classe Stat, composta da 47 metodi in grado di calcolare disposizioni,
permutazioni, dismutazioni, combinazioni semplici, la speranza matematica, la varianza e la media di un
campione, gli intervalli di fiducia e i test di Student per uno e due campioni. Può inolte calcolare la
cumulative distrubution function della distribuzione normale tramite il metodo CdfN che utilizza a sua volta
il metodo Erf che restituisce il valore dell'integrale
x
2
e−t dt .
√π ∫
2
0
➢ IL METODO ERF
Soffermiamoci ora sul metodo Erf(double x) della classe Stat. Sappiamo che la funzione errore è
definita dall'integrale sopracitato, rendendola difficile da calcolare in Java senza approssimazioni. Si è
quindi ricorso alla serie di Taylor per descrivere la funzione come la sommatoria
m
i
2i+1
(−1) x
2
Erf ( x) := √ π ∑
i =0 i !( 2i+1)
( con m → ∞) .
Questo procedimento ha permesso d'implementare la funzione in Java tramite un metodo iterativo,
quindi semplice ed efficacie da utilizzare in un calcolatore. Per ottenere valori approssimati al meglio
sarebbe necessario imporre m più grande possibile, tenendo però conto della velocità di calcolo e, data la
presenza di un fattoriale dell'indice, la capacità massima di cifre a disposizione nel calcolatore.
Risolviamo questi problemi con delle veloci verifiche empiriche. Con il comando Double.MAX_VALUE
vediamo che il massimo numero consentito è 1.7976931348623157E308. In seguito verifichiamo per
quale m il suo fattoriale è minore del valore massimo appena trovato. Si ottiene che la m cercata vale 170,
quindi non ha senso (e potrebbe essere molto dannoso ai fini della precisione di calcolo) porre m>170.
Scritto il metodo che implementa
170
(−1)i x 2i+1
2
∑
√π
i=0 i ! (2i+1)
dobbiamo verificare che il tempo d'esecuzione sia ottimale. Tramite una classe prova creata ad hoc, si
verifica la velocità del calcolo di Erf(x) per 0⩽x<6 con definizione 0,01. I risultati dimostrano che
la media è di circa 0,085 ms, con un massimo di 0,133 ms, tempo più che accettabile. Come
ultima analisi, vediamo l'errore di approssimazione di tale metodo (confrontato con i valori
ottenuti in Matlab):
1
SVILUPPO DI UNA CLASSE STATISTICA IN AMBIENTE JAVA
POTOK MARCO
Si conclude che l'errore è molto limitato, con valore massimo di 7,1863E-10 ed è pari a zero per valori di
x minori di 3,5 e maggiori di 5,1.
➢ LE CLASSI EX_C ED EX_G
Queste classi contengono un metodo che utilizza la classe Stat per risolvere gli esercizi C e G assegnati
come compiti per casa.
Nell'esercizio C come primo punto è rischiesta la probabilità che in 13 lanci di una moneta regolare esca
esattamente 3 volte testa. La risoluzione è semplice e consta nello stampare a video il rapporto tra la
combinazione C13,3 che rappresenta i casi favorevoli e i 213 casi possibili. Il risultato è inoltre arrotondato
a 4 cifre significative ed espresso anche in forma percentuale. Vediamo il codice Java:
short N=13;
double pa=Stat.combS(N,3)/Math.pow(2,N);
System.out.println("La probabilità che esca testa esattamente
"+Stat.Round(pa,4)+", cioè: "+Stat.Round(pa*100,1)+"%.");
3
volte
è:
e stampa a video:
La probabilità che esca testa esattamente 3 volte è: 0.0349, cioè: 3.5%.
Similmente si è proceduto con il secondo punto dell'esercizio, calcolando le probabilità che la testa esca
almeno 3 volte su 13 lanci:
double pb=1-(Stat.combS(N,2)-Stat.combS(N,1))/Math.pow(2,N);
System.out.println("La
probabilità
che
esca
testa
almeno
"+Stat.Round(pb,4)+", cioè:"+Stat.Round(pb*100,1)+"%.");
3
volte
è:
con relativa risposta:
La
probabilità
che
esca
testa
almeno
3
volte
è:
0.9921,
cioè:
99.2%.
2
SVILUPPO DI UNA CLASSE STATISTICA IN AMBIENTE JAVA
POTOK MARCO
vengono invece richieste le probabilità: X Cauchy per P ( X <b),
Y N ( µ=3, s =2) per P (a≤ y≤b) e W lnN ( µ=7, s 2=1.1) per P ( w≥b) , con a=113 /1013
e b=1013/ 213. Nella classe Stat sono stati implementati 3 metodi appositi per calcolare la probabilità
dei vari intervalli tramite la funzione di ripartizione corrispondente. I codici risultamo quindi molto
semplici:
Nell'esercizio
G
2
double F_b=Stat.Cauchy_F(b);
double nP=Stat.NormalP(3,2,a,b);
double lnNP=Stat.lnNormalP(7,1.1,b,'>').
➢ ESERCIZI D'ESAME
Con le tre classi Ex_3_110718, Ex_2_120220 ed Ex_3_120618 si dimostra come in un solo comando si
possa risolvere un intero quesito d'esame. Nel primo caso il terzo esercizio proposto all'esame del 18
luglio 2011 richiede, dati due campioni, di verificare con i test statistici se µ x ≠0 (contro µ x ≠ 0) e
l'ipotesi µ x =µ y (contro µ x ≠ µ y ). Nella classe Stat sono stati implementati due metodi STest(double[ ]
x, double m, double a, char c) e STest(double[ ] x, double[ ] y, double a, char c) che svolgono le
verifiche per il test di Student. Vediamo i codici Java:
public static Boolean Stest(double[ ] x, double m, double a, char c)
{
if(c=='<') return T_n(x,m)>Tstud(x.length-1, 1-a);
if(c=='=') return Math.abs(T_n(x,m))<Tstud(x.length-1, 1-a/2);
else return null;
}
public static Boolean Stest(double[ ] x, double[ ] y, double a, char c)
{
if(c=='>') return Math.abs(T_n(x,y))>Tstud(x.length+y.length-2, 1-a);
if(c=='=') return Math.abs(T_n(x,y))<Tstud(x.length+y.length-2, 1-a/2);
else return null;
}
Questi permettono di risolvere il quesito e stampare a video la soluzione utilizzando solamente quattro
semplici linee di codice:
double[] x={.3,2.2,-.5,-.2,1,2.1}, y={-2.2,.5,-.3,.2,-2.1,-1};
double a=.05;
System.out.println("L'ipotesi µx=0"+(Stat.STest(x,0,a,'=')?" non":"")+" è respinta
al livello "+a+".");
System.out.println("L'ipotesi
µx=µy"+(Stat.STest(x,y,a,'=')?"
non":"")+"
è
respinta al livello "+a+".")
che stampano le relative risposte:
L'ipotesi µx=0 non è respinta al livello 0.05.
L'ipotesi µx=µy è respinta al livello 0.05.
che corrispondono alle soluzioni messe in rete. Similmente e con ugual successo è stato risolto l'esercizio
3 del 18 giugno 2012, con output:
L'ipotesi µx=µy non è respinta al livello 0.05.
L'ipotesi µx=µy non è respinta al livello 0.01.
Ora vediamo come è stato possibile risolvere l'esercizio 2 del 20 febbraio 2012, in cui si chiede di trovare
prima il valore di un elemento c di un campione 0,11 0,05 c la cui media è 0,09, quindi gli intervalli di
fiducia consueti per µ ai livelli 0,05 e 0,01. Prima di tutto il valore di c è stato trovato con un banale
calcolo:
c=.09*3-.11-.05;
3
SVILUPPO DI UNA CLASSE STATISTICA IN AMBIENTE JAVA
POTOK MARCO
Si definisce quindi il campione da analizzare e si usa il metodo ConfIntMeanPrint(double[ ] x, double
a, int c) per stampare a video l'intervallo di confidenza richiesto. Il codice è:
double[ ] a={.11,.05,c};
System.out.print ("L'intervallo di fiducia del campione gaussiano a livello "+a1+"
è: ");
Stat.ConfIntMeanPrint(a,a1,4);
System.out.print ("L'intervallo di fiducia del campione gaussiano a livello "+a2+"
è: ");
Stat.ConfIntMeanPrint(a,a2,4);
Con relativa risposta:
L'intervallo di fiducia del campione gaussiano a livello 0.05 è: [0.0039,0.1761]
L'intervallo di fiducia del campione gaussiano a livello 0.01 è: [-0.1085,0.2885]
➢ CONCLUSIONE
È stato possibile realizzare l'idea iniziale che prevedeva di creare un programma Java in grado di risolvere
alcuni dei principali problemi statistici proposti nel corso di Metodi Statistici e Processi Stocastici 2011/2012.
Sono stati presi ad esempio cinque esercizi tra compiti per casa e temi d'esame, riuscendo a ricavare un
risultato preciso per ogni quesito, mantenendo sempre una notevole facilità d'utilizzo del codice, tanto
da richiederne poche righe per ogni esercizio. Successivamente alla stesura della presente tesina, il
programma è stato ulteriormente sviluppato ed ottimizzato. In particolare ora è possibile calcolare: le
funzioni gamma e beta standard, incomplete, regolarizzate incomplete. Altri metodi calcolano la
funzione di densità, di ripartizione e i quantili della distribuzione normale, come della distribuzione di
Student e del chi-quadrato. In futuro è previsto un'ulteriore sviluppo, ampliando così ulteriormente la
classe Stat che potrà risolvere gran parte dei problemi statistici.
➢ FONTI
- Appunti delle lezioni del corso Metodi Statistici e Processi Stocastici 2010/2011 – 2011/2012
- Wikipedia: http://en.wikipedia.org/wiki/Error_function
http://en.wikipedia.org/wiki/Normal_distribution
http://en.wikipedia.org/wiki/Student_t_distribution
http://en.wikipedia.org/wiki/Gamma_function
http://en.wikipedia.org/wiki/Beta_function
http://en.wikipedia.org/wiki/Pochhammer_symbol
- Mathworld: http://mathworld.wolfram.com/IncompleteBetaFunction.html
➢ PROGRAMMI UTILIZZATI
- DrJava (drjava-20110822-r5448)
- Matlab R2010a
4