Statistiche sulla mia vita Ho monitorato le mie abitudini per un anno, e questo è quello che ho imparato

Statistiche sulla mia vita Monitoraggio delle mie abitudini per un anno, ecco cosa ho imparato

Ho misurato il tempo che ho trascorso nelle mie attività quotidiane (studiare, fare sport, socializzare, dormire…) per 332 giorni di seguito

Perché? Solo perché avrei fatto questo?

Probabilmente questo è l’esperimento più lungo e più impegnativo che abbia mai fatto nella mia vita. Inoltre, ha scarsa rilevanza scientifica, poiché il campione di popolazione è solo una persona, ed è altamente soggettivo (si basa completamente sulla mia memoria e percezione del tempo).

Allora perché farlo? Le routine, come qualsiasi altro metodo di responsabilizzazione personale, mi aiutano in molti modi diversi. Ho iniziato questo esperimento in un momento basso della mia vita, cercando di studiare me stessa e come abitudini diverse potessero influire sul mio umore e sulla mia salute mentale. Lo scopo era “hackare” il mio stesso cervello: se sapessi – statisticamente – cosa mi rende felice e sana nel lungo termine (e cosa fa l’opposto!), sarei in grado di migliorare la mia vita e potenzialmente dare consigli o aiutare persone simili a me che stanno attraversando momenti difficili.

E perché questo ti interesserebbe?

Credo che questo esercizio introspettivo sia un ottimo esempio di come la scienza dei dati possa essere applicata a qualsiasi cosa. Ovviamente, non è necessario fare questo tipo di tracciamento e diario. Puoi studiare qualsiasi cosa tu trovi preziosa nella tua vita: tracciare il comportamento del tuo animale domestico, il clima della tua città, il tasso di ritardo nel sistema di trasporto pubblico locale… Ci sono molte analisi personali da fare: se c’è un set di dati, puoi studiarlo! Fortunatamente, i dati sono ovunque, devi solo cercare nel posto giusto e tenerne traccia.

Il metodo – cosa ho fatto e come l’ho fatto?

Ogni giorno ho dedicato alcuni minuti a prendere appunti personali su ciò che ho fatto e ho tenuto traccia del tempo trascorso (in ore) in diverse attività e categorie.

Le variabili che ho misurato sono cambiate leggermente nel corso dell’anno: alcune sono apparse, alcune sono scomparse e altre si sono fuse insieme. Le finali, e quelle per le quali ho dati per tutti i record, sono le seguenti: Sonno, Scrittura, Studio, Sport, Musica, Igiene, Lingue, Lettura, Socializzazione e Umore – un totale di dieci variabili che coprono ciò che ritengo essere gli aspetti più importanti della mia vita.

Esplorazione iniziale dei dati

Ho iniziato guardando le serie storiche individuali per quattro variabili: Sonno, Studio, Socializzazione e Umore. Ho utilizzato Microsoft Excel per disegnare rapidamente alcuni grafici. Essi rappresentano il numero giornaliero di ore trascorse (blu) e la media mobile¹ per cinque giorni MA(5) (rosso), che ho considerato essere una buona misura per la mia situazione. La variabile umore è stata valutata da 10 (il migliore!) a 0 (orribile!).

Riguardo ai dati contenuti nella nota a piè di pagina di ciascun grafico: il totale è la somma dei valori delle serie, la media è la media aritmetica della serie, DEV è la deviazione standard e DEV rel è la deviazione standard divisa per la media.

Totale: 2361h. Media: 7,1h. DEV: 1,1h. DEV rel: 15,5% (immagine dell'autore).

Tutto sommato, ho dormito abbastanza bene. Ho avuto giorni difficili, come tutti gli altri, ma penso che la tendenza sia abbastanza stabile. Infatti, è una delle variabili che meno varia nel mio studio.

Totale: 589,1h. Media: 1,8h. DEV: 2,2. DEV rel: 122% (immagine dell'autore).

Ecco le ore che ho dedicato alla mia carriera accademica. Fluttua molto – trovare un equilibrio tra lavoro e studio spesso significa dover comprimere i progetti durante il fine settimana – ma comunque mi considero soddisfatto.

Totale: 1440,9h. Media: 4,3h. Deviazione standard: 4,7h. Deviazione relativa: 107% (immagine dell'autore).

Riguardo a questa tabella, posso solo dire che sono sorpreso. Il totale è maggiore di quanto mi aspettassi, considerando che sono introverso. Naturalmente, le ore trascorse con i colleghi all’università contano anche. In termini di variabilità, la deviazione standard è molto elevata, il che ha senso considerando la difficoltà di avere una routine stabilita per quanto riguarda la socializzazione.

Media: 8,0h. Deviazione standard: 0,9h. Deviazione relativa: 11,3% (immagine dell'autore).

Questa serie è la meno variabile – la deviazione relativa è la più bassa tra le variabili studiate. A priori, sono soddisfatto della tendenza osservata. Ritengo che sia positivo mantenere un umore piuttosto stabile – e ancora meglio se è positivo.

Studio di correlazione

Dopo aver analizzato le tendenze delle principali variabili, ho deciso di approfondire e studiare le potenziali correlazioni² tra di esse. Poiché il mio obiettivo era quello di essere in grado di modellare e predire (o almeno spiegare) “Umorismo”, le correlazioni erano una metrica importante da considerare. Da esse ho potuto estrarre relazioni come le seguenti: “i giorni in cui studio di più sono quelli in cui dormo di meno”, “di solito studio lingue e musica insieme”, ecc.

Prima di fare qualsiasi altra cosa, apriamo un file Python e importiamo alcune librerie chiave per l’analisi delle serie. Di solito uso alias per esse, poiché è una pratica comune e rende il codice meno verboso.

import pandas as pd               #1.4.4import numpy as np                #1.22.4import seaborn as sns             #0.12.0import matplotlib.pyplot as plt   #3.5.2from pmdarima import arima        #2.0.4

Faremo due studi diversi riguardo alla correlazione. Esamineremo il coefficiente di correlazione di Pearson³ (per le relazioni lineari tra variabili) e il coefficiente di correlazione di Spearman⁴ (che studia le relazioni monotone tra variabili). Utilizzeremo la loro implementazione⁵ in pandas.

Matrice di correlazione di Pearson

Il coefficiente di correlazione di Pearson tra due variabili X e Y viene calcolato nel seguente modo:

dove cov è la covarianza, sigma X è std(X) e sigma Y è std(Y)

Possiamo calcolare rapidamente una matrice di correlazione, in cui viene calcolata ogni possibile correlazione a coppie.

#leggi, seleziona e normalizza i datiraw = pd.read_csv("final_stats.csv", sep=";")numerics = raw.select_dtypes('number')#calcola la matrice di correlazionecorr = numerics.corr(method='pearson')#genera la heatmapsns.heatmap(corr, annot=True)#disegna il plotplt.show()

Questa è la matrice di correlazione di Pearson grezza ottenuta dai miei dati.

Matrice di correlazione di Pearson per le mie variabili (immagine dell'autore).

E questi sono i valori significativi⁶, quelli che sono, con una confidenza del 95%, diversi da zero. Effettuiamo un test t⁷ con la seguente formula. Per ogni valore di correlazione rho, lo scartiamo se:

dove n è la dimensione del campione. Possiamo riutilizzare il codice precedente e aggiungere in questo filtro.

#constantsN=332 #numero di campioniSTEST = 2/np.sqrt(N)def significance_pearson(val):    if np.abs(val)<STEST:        return True    return False#read dataraw = pd.read_csv("final_stats.csv", sep=";")numerics = raw.select_dtypes('number')#calculate correlationcorr = numerics.corr(method='pearson')#prepare masksmask = corr.copy().applymap(significance_pearson)mask2 = np.triu(np.ones_like(corr, dtype=bool)) #rimuove la parte triangolare superiormask_comb = np.logical_or(mask, mask2)c = sns.heatmap(corr, annot=True, mask=mask_comb)c.set_xticklabels(c.get_xticklabels(), rotation=-45)plt.show()

Quelli scartati potrebbero essere solo rumore e rappresentare erroneamente tendenze o relazioni. In ogni caso, è meglio supporre che una vera relazione sia insignificante che considerare significativa una che non lo è (quello a cui ci riferiamo come errore di tipo II che viene favorito rispetto all’errore di tipo I). Questo è particolarmente vero in uno studio con misurazioni piuttosto soggettive.

Matrice di correlazione di Pearson filtrata. I valori non significativi (e la parte triangolare superiore) sono stati filtrati. (immagine dell'autore)

Coefficiente di correlazione di rango di Spearman

Il coefficiente di correlazione di Spearman può essere calcolato come segue:

dove R indica la variabile di rango⁸ — le altre variabili sono le stesse descritte nel coef Pearson.

Come abbiamo fatto in precedenza, possiamo calcolare rapidamente la matrice di correlazione:

#read, select and normalize the dataraw = pd.read_csv("final_stats.csv", sep=";")numerics = raw.select_dtypes('number')#compute the correlation matrixcorr = numerics.corr(method='spearman') #attenzione a questo cambio!#generate the heatmapsns.heatmap(corr, annot=True)#draw the plotplt.show()

Questa è la matrice di correlazione grezza di Spearman ottenuta dai miei dati:

Matrice di correlazione di Spearman per le mie variabili (immagine dell'autore).

Vediamo quali valori sono effettivamente significativi. La formula per verificare la significatività è la seguente:

dove r è il coefficiente di Spearman. Qui, t segue una distribuzione di student t con n-2 gradi di libertà.

Qui, filtreremo tutti i valori t più alti (in valore assoluto) di 1,96. Di nuovo, il motivo per cui sono stati scartati è che non siamo sicuri che siano rumore — casualità casuale — o una vera tendenza. Codifichiamolo:

# costantiN=332 # numero di campioniTTEST = 1.96def importanzeigen_spearman(val):    if val==1:        return True    t = val * np.sqrt((N-2)/(1-val*val))        if np.abs(t)<1.96:        return True    return False#leggi dataraw = pd.read_csv("final_stats.csv", sep=";")numerics = raw.select_dtypes('number')#calcola la correlazionecorr = numerics.corr(method='spearman')#prepara i maschermask = corr.copy().applymap(significance_spearman)mask2 = np.triu(np.ones_like(corr, dtype=bool)) #rimuovi il triangolo superioremask_comb = np.logical_or(mask, mask2)#plotta i risultatic = sns.heatmap(corr, annot=True, mask=mask_comb)c.set_xticklabels(c.get_xticklabels(), rotation=-45)plt.show()

Ecco i valori significativi.

Matrice di correlazione con valori significativi. (immagine dell'autore)

Credo che questo grafico spieghi meglio le relazioni apparenti tra le variabili, poiché il suo criterio è più “naturale” (considera le funzioni e le relazioni monotone⁹, e non solo lineari). Non è influenzato in modo significativo dagli outliers come l’altro (un paio di giorni molto negativi relativi a una certa variabile non influiranno sul coefficiente di correlazione complessivo).

Tuttavia, lascerò entrambi i grafici al lettore per giudicare ed estrarre le proprie conclusioni.

Studi sulle serie temporali – Modelli ARIMA

Possiamo trattare questi dati come una serie temporale. Il tempo potrebbe essere un fattore importante nell’esplicazione delle variabili: alcune di esse potrebbero fluttuare periodicamente o essere autocorrelate¹⁰. Ad esempio, una brutta notte potrebbe farmi venire sonno e causarmi un eccesso di sonno il giorno successivo – questa sarebbe una correlazione temporale. In questa sezione, mi concentrerò solo sulle variabili dell’esplorazione iniziale.

Esploreremo il modello ARIMA e troveremo una buona adattamento per i nostri dati. Un modello ARIMA¹¹ è una combinazione di un modello auto-regressivo (AR¹²) e una media mobile – da qui le sue iniziali (Auto-Regressione Integrata Media Mobile). In questo caso, utilizzeremo il metodo auto_arima di pmdarima, una funzione ispirata alla funzione “forecast::autoarima” di R, per determinare i coefficienti per il nostro modello.

for v in ['Sonno','Studio','Socializzazione','Umore']:    arima.auto_arima(numerics[v], trace=True) #trace=True per vedere i risultati

I risultati sono stati riassunti nella seguente tabella:

Modelli ARIMA(p,d,q) con i relativi AIC (immagine dell'autore).

<p+sorprendentemente, -="" ar(1)="" arima(1,0,0)="" auto-regressivo,="" bene="" che="" ciò="" come="" d="" d-1,="" da="" dal="" dall'umore="" distribuito="" e="" giorno="" il="" implica="" in="" l'umore="" l'umore.="" lo="" ma="" modo="" non="" normale.

Nonostante sembri piccolo, questa conseguenza è abbastanza interessante. Anche lo Studio è auto-regressivo, ma segue un ARIMA(1,0,2) – il che significa che non segue direttamente un trend, ma la sua media mobile lo fa. Tuttavia, l’AIC¹³ per questo è considerevolmente più alto, quindi è possibile che il modello potrebbe stare complicando eccessivamente l’esplicazione del comportamento osservato.

FFT (Trasformata di Fourier veloce)

Possiamo utilizzare una Trasformata di Fourier Discreta¹⁴ per analizzare i nostri dati. Con essa, dovremmo essere in grado di notare eventuali pattern legati alla stagionalità. La Trasformata di Fourier è un’operazione di trasformazione dei dati in grado di scomporre una serie nei suoi componenti di base. Ciò può essere compreso meglio attraverso l’immagine qui sotto:

Il processo (simplified) della trasformata di Fourier (immagine dell'autore)

Ecco un altro esempio: abbiamo un segnale composto da due funzioni sinusoidali con frequenza 1 e 10 rispettivamente. Dopo aver applicato la FT, vediamo questo:

Come possiamo vedere, FFT scompone i segnali nei loro componenti di frequenza (immagine da Wikimedia Commons)

Il risultato è un grafico con due picchi, uno a x=1 e uno a x=10. La Trasformata di Fourier ha trovato le componenti di base del nostro segnale!

Trasformiamo questo in codice:

per v in ['Sleep','Studying','Socializing','Mood']:    t = np.arange(0,N,1)    x = numerics[v]    X = np.fft.fft(x)    n = np.arange(0,len(X),1)    T = N    freq = n/T     plt.figure(figsize = (8, 4))    plt.subplot(121)    plt.plot(t, x, 'r')    plt.xlabel('Tempo (giorni)')    plt.ylabel(v)    plt.subplot(122)    plt.stem(n, np.abs(X), 'b', markerfmt=" ", basefmt="-b")    plt.xlabel('Freq (1/giorni)')    plt.ylabel('FFT |X(freq)|')    plt.xlim(0, 30)    plt.ylim(0, 500)    plt.tight_layout()    plt.show()

Tornando al nostro studio di caso, questi sono i risultati che il nostro codice produce:

Da sinistra a destra e dall'alto verso il basso: grafici per Sleep, Studying, Socializing e Mood. (immagine dell'autore)

Possiamo osservare che Sleep ha un valore significativo alla frequenza 1, il che significa che i dati seguono un ciclo di 1 giorno, il che non è molto utile. Studying presenta valori interessanti: i primi cinque circa sono notevolmente più alti degli altri. Sfortunatamente, il rumore prevale su di loro e su ogni altro grafico: non è possibile ottenere conclusioni con certezza.

Per contrastare ciò, eliminiamo il rumore con una media mobile. Proviamo ad applicare di nuovo MA(5) e studiamo la FFT. Il codice sarà quasi lo stesso, tranne per la media mobile.

def moving_average(x, w):    return np.convolve(x, np.ones(w), 'valid') / wk = 5per v in ['Sleep','Studying','Socializing','Mood']:    t = np.arange(0,N-k+1,1)    x = moving_average(numerics[v], k)    X = np.fft.fft(x)    n = np.arange(0,len(X),1)    T = N-k+1    freq = n/T    plt.figure(figsize = (8, 4))    plt.subplot(121)    plt.plot(t, x, 'r')    plt.xlabel('Tempo (giorni)')    plt.ylabel(v)    plt.subplot(122)    plt.stem(n, np.abs(X), 'b', markerfmt=" ", basefmt="-b")    plt.xlabel('Freq (1/giorni)')    plt.ylabel('FFT |X(freq)|')    plt.xlim(0, 30)    plt.ylim(0, 500)    plt.tight_layout()    plt.show()

Questi sono i grafici generati dal nostro codice:

Da sinistra a destra e dall'alto verso il basso: grafici per Sleep, Studying, Socializing e Mood. (immagine dell'autore)

Dopo l’applicazione del MA, il rumore è stato leggermente ridotto. Tuttavia, sembra che non ci siano conclusioni da trarre da queste analisi, in quanto non riusciamo a individuare valori significativi e chiari della frequenza.

Conclusioni

Dopo aver condotto diversi studi statistici, possiamo concludere quanto era atteso: il comportamento umano è molto complicato, certamente più di quanto un foglio di Excel e un paio di modelli matematici possano tener conto. Tuttavia, c’è un valore da trovare sia nella raccolta metodica dei dati che nelle opportunità di analisi che ne derivano. Facciamo una rapida panoramica di ciò che abbiamo fatto:

  • Analisi dei dati grezzi e delle tendenze.
  • Analisi di correlazione di Pearson e Spearman e test di significatività.
  • Adeguamento del modello ARIMA.
  • Decomposizione della Trasformata Discreta di Fourier veloce.

Dopo aver effettuato queste analisi, siamo stati in grado di trarre alcune conclusioni sui nostri dati e su come le diverse variabili si correlano tra loro. Ecco un riassunto delle nostre scoperte.

  • In termini di deviazione relativa (variabilità), l’Umore e il Sonno sono stati i più bassi (rispettivamente 11,3% e 15,5%), mentre lo Studio e il Socializzare erano entrambi superiori al 100%.
  • Il Socializzare è risultato correlato in modo negativo con quasi tutti i miei hobby, ma positivamente con il mio Umore (sia secondo Pearson che secondo Spearman). Questo è probabilmente dovuto al fatto che quando incontro amici o familiari, devo mettere da parte i miei hobby per il giorno, ma generalmente sono più felice di quanto lo sarei da solo.
  • L’Umore e la Scrittura sono correlati in modo negativo (Spearman), ciò può essere spiegato dal fatto che a volte sfogo i miei problemi attraverso brevi storie o scrivendo sul mio diario.
  • È emerso che l’Umore e lo Studio sono autoregressivi nello studio di adattamento ARIMA, il che implica che il valore in un certo giorno può essere spiegato dal valore del giorno precedente.
  • Non è stata trovata alcuna decomposizione chiara con la Trasformata Discreta di Fourier, anche se alcuni gruppi di frequenze si sono evidenziati rispetto ad altri.

È interessante notare che abbiamo ottenuto dati statistici “globali”, che sebbene non abbiano un significato scientifico, sono comunque interessanti da conoscere.

Personalmente, penso che questo esperimento mi sia stato utile. Anche se i risultati finali non sono conclusivi, credo che mi abbia aiutato a affrontare i momenti difficili e a tenere traccia di quelli positivi. Allo stesso modo, penso che sia sempre positivo fare un po’ di introspezione e conoscere se stessi meglio.

Come ultima nota, questo è il grafico cumulativo, realizzato nuovamente in MS Excel, per tutte le variabili che possono essere accumulate (tranne umore e igiene, che non vengono conteggiate in ore ma in una determinata classifica; e sonno). Ho deciso di tracciarlo come un grafico logaritmico perché anche se le variabili accumulate erano lineari, le loro pendenze variabili rendevano difficile per il visualizzatore vedere i dati. Ecco a voi!

Somma cumulativa di ogni serie, asse Y logaritmico. (immagine dell'autore)

Come sempre, vi incoraggio a commentare eventuali pensieri o dubbi che potreste avere.

Codice e dati sono disponibili su GitHub.

GitHub – Nerocraft4/habittracker

Contribuisci allo sviluppo di Nerocraft4/habittracker creando un account su GitHub.

github.com

Riferimenti

[1] Wikipedia. Media mobile. https://it.wikipedia.org/wiki/Media_mobile

[2] Wikipedia. Correlazione. https://it.wikipedia.org/wiki/Correlazione

[3] Wikipedia. Coefficiente di correlazione di Pearson. https://it.wikipedia.org/wiki/Coefficiente_di_correlazione_di_Pearson

[4] Wikipedia. Coefficiente di correlazione di Spearman. https://it.wikipedia.org/wiki/Coefficiente_di_correlazione_di_Spearman

[5] Documentazione di Pandas. pandas.DataFrame.corr. https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.corr.html

[6] Wikipedia. Significatività statistica. https://it.wikipedia.org/wiki/Significatività_statistica

[7] Wikipedia. Test t di Student. https://it.wikipedia.org/wiki/Test_t_di_Student

[8] Wikipedia. Correlazione di rango. https://it.wikipedia.org/wiki/Correlazione_di_rango

[9] Wolfram MathWorld. Funzione monotona. https://mathworld.wolfram.com/MonotonicFunction.html

[10] Wikipedia. Autocorrelazione. https://it.wikipedia.org/wiki/Autocorrelazione

[11] Wikipedia. Media mobile autoregressiva integrata. https://it.wikipedia.org/wiki/Media_mobile_autoregressiva_integrata

[12] Wikipedia. Modello autoregressivo. https://it.wikipedia.org/wiki/Modello_autoregressivo

[13] Science Direct. Criterio di informazione di Akaike. https://www.sciencedirect.com/topics/social-sciences/akaike-information-criterion

[14] Wikipedia. Trasformata discreta di Fourier. https://it.wikipedia.org/wiki/Trasformata_discreta_di_Fourier