bigdata

Cominciamo con il calcolo del minimo, del massimo e della media di un insieme di valori.

Nella rappresentazione in figura ho voluto dare una collocazione logico funzionale agli argomenti trattati mettendoli in relazione con l'obiettivo finale, che a sua volta è il punto di partenza per i successivi obiettivi. Attenzione che la figura non definisce il rapporto tra gli argomenti, indica la logica del percorso sviluppato in questo post e nei successivi: gli argomenti "statistica" e "probabilità" forniscono gli strumenti per analizzare i dati raccolti; per mezzo di queste analisi è possibile formulare delle "ipotesi" dalle quali si può dedurre lo scenario successivo tramite inferenza.

Nel primo passo di questo percorso è necessario disporre di un insieme di dati campione sul quale effettuare un'analisi statistica. L'esempio che ho scelto è l'insieme dei pesi di giovani studenti di una scuola primaria appartenenti allo stesso anno.

Dal manuale Swift al capitolo Collection Types si ricava che abbiamo a disposizione tre tipi di contenitori:

  1. Set: una collezione non ordinata di valori unici.
  2. Dictionary: una collezione non ordinata di associazioni chiave-valore.
  3. Array: una collezione ordinata di valori.

Ragionando su quale sia il contenitore più idoneo a raccogliere i dati dobbiamo escludere Set e Dictionary. Il primo in quanto l'insieme potrebbe avere dei doppi con studenti di ugual peso e il contenitore Set deve avere valori unici. Il secondo potrebbe tornare utile se volessi usare una chiave arbitraria per identificare ogni studente in modo univoco, come ad esempio il codice fiscale, ma non è questo il caso: in questa analisi non interessa identificare ogni singolo studente ma effettuare un ragionamento sull'insieme.

Utilizzo quindi l'array e lo riempio con i valori dei pesi di 90 studenti (per esempio tre classi prime). Per riempire l'array con valori quasi casuali utilizzo la funzione arc4random_uniform() impostandola per restituire valori compresi tra 15 e 35.

var pesiStudenti = [Int]()

for index in 0...89 {

    pesiStudenti.append(Int(arc4random_uniform(20)+15))

 


arc4random_uniform(20)
restituisce un valore casuale tra 0 e 20, a questo valore viene sommato 15 spostando il range tra 15 e 35. Questo è un esempio del risultato ottenuto nell'array pesiStudenti dalla generazione casuale:

[32, 27, 21, 24, 31, 33, 26, 28, 18, 27, 20, 23, 29, 20, 15, 26, 27, 30, 20, 24, 33, 28, 31, 28, 29, 17, 33, 24, 17, 31, 31, 29, 18, 23, 18, 29, 16, 24, 24, 27, 28, 24, 33, 27, 26, 24, 30, 24, 28, 25, 17, 16, 30, 15, 20, 27, 19, 24, 24, 30, 32, 30, 18, 34, 28, 29, 28, 16, 34, 15, 30, 15, 27, 31, 25, 34, 19, 24, 24, 18, 22, 18, 20, 31, 15, 34, 34, 32, 18, 22] 


Un primo facile riscontro da questo insieme di dati è quello di ricavare qual'è il peso inferiore e quello superiore. Questi valori si ricavano con le rispettive funzioni.

let pesoInferiore = pesiStudenti.min()

let pesoSuperiore = pesiStudenti.max()

 

Questi sono i valori che si ottengono dall'array esempio sopra riportato.

pesoInferiore: 15
pesoSuperiore: 34


Le funzioni min() e max() fanno parte del tipo array. Per quanto queste informazioni possano sembrare banali ai fini statistici permettono di calcolare la misura della dispersione che è l'intervallo tra il valore massimo e il minimo (34-15=19); nel caso specifico la dispersione dei pesi della popolazione composta dai bambini delle tre classi è 19Kg.

Più interessante potrebbe essere la media dei pesi degli studenti dell'anno in corso, se venisse paragonata ai valori medi ricavati negli anni precedenti potrebbe fornire un'informazione sulle abitudini alimentari. La media viene anche definita come misura della tendenza centrale, riporto questa definizione per enfatizzare l'importanza del valore medio. Il tipo array non dispone di una funzione apposita per calcolare la media, è però possibile aggiungerla tramite le extensions.

extension Collection where Iterator.Element == Int, Index == Int {

    var media: Double {

        if isEmpty {

            return 0

        }

        return Double(reduce(0, +)) / Double(endIndex-startIndex)

    }

}

 

let mediaPesi = pesiStudenti.media

 

Dai valori sopra riportati si ricava questa media.

 mediaPesi: 25.1

Se non c'è ancora confidenza con Swift il codice sopra esposto può sembrare disarmante. Collection è un protocollo a cui i tipi set, dictionary ed array si conformano. E' possibile estendere il tipo Collection aggiungendo una computed property che calcola la media degli elementi della Collection. Viene creata la variabile media che nel caso la Collection non sia vuota restituisce un valore Double calcolato dividendo il valore ottenuto con reduce per il numero di elementi della Collection. Ricordo che reduce riduce tutti gli elementi dell'array ad un singolo valore in questo caso tramite l'operazione somma (indicata dal simbolo +); la somma viene poi divisa per il numero di elementi, qui calcolato sottraendo l'indice finale dell'array a quello iniziale.

Nell'ultima riga, viene calcolata la media; questo è reso possibile in quanto la variabile pesiStudenti è stata precedentemente definita come array, ed essendo di conseguenza conforme al protocollo Collection ne acquisisce automaticamente la nuova computed property media.

Infine consideriamo la proposizione where che pone dei vincoli agli elementi gestiti dalla procedura. Iterator è un tipo che Swift utilizza per ciclare sugli elementi di un insieme, in questo caso di un array. Il vincolo che la proposizione where impone è che l'elemento dell'array restituito durante ogni ciclo sia di tipo Int, così come l'indice dell'array. In pratica l'estensione sopra definita può essere eseguita tutte le volte che il vincolo viene soddisfatto. Non specificare questo vincolo rende la computed property media non compilabile e genera di conseguenza un errore Swift.

Un'ultima osservazione. Rilanciando il programma più volte la generazione casuale di valori porterà a ricavare array tra loro diversi ma che, in molti casi, avranno in comune i medesimi valori minimi e massimi. Ne consegue che minimo e massimo sono strumenti non particolarmente utili per analizzare un insieme di valori. La media fornisce un aiuto più efficace per dedurre la tendenza dei valori di un insieme. Nei prossimi appunti andremo alla scoperta di nuovi strumenti che hanno questo scopo.