Salta al contenuto
Note per Studenti Python per il machine learning - NumPy, pandas e Matplotlib

Python per il machine learning - NumPy, pandas e Matplotlib

In questa pagina 6

Gli strumenti del corso: Python con le librerie NumPy, pandas, Matplotlib, seaborn e scikit-learn. Non si insegna la programmazione, ma si fissano le abitudini che servono nei laboratori e all'esame; i calcoli statistici corrispondenti sono in Statistica per il machine learningI dati di un problema ML si organizzano nella matrice di progetto $X$ ($n$ osservazioni, $p$ variabili). La statistica serve a capirli, ripulirli e prepararli: i momenti (media $\mu$, varianza $\sigma^2$, asimmetria, curtosi), i quartili con lo scarto interquartile $\mathrm{IQR}=Q_3-Q_1$ (all'esame senza interpolazione), la moda per i dati categorici. Con queste quantità si imputano i dati mancanti (media o mediana), si eliminano le variabili costanti e si standardizza con lo z-score $z=(x-\mu)/\sigma$, usando sempre media e deviazione standard del solo training set.Statistica per il machine learning → e Correlazione e visualizzazione dei datiLa correlazione di Pearson $r=\sum(X_i-\bar X)(Y_i-\bar Y)/\big(\sqrt{\sum(X_i-\bar X)^2}\sqrt{\sum(Y_i-\bar Y)^2}\big)\in[-1,1]$ misura la relazione lineare tra due variabili (covarianza divisa per le deviazioni standard); correlazione non implica causalità. Serve a capire quali variabili contano per il target e a eliminare quelle quasi duplicate (|r| molto alto). Gli indicatori di sintesi non bastano (quartetto di Anscombe, Datasaurus): vanno affiancati ai grafici: istogramma, KDE, box plot, violin plot, heatmap di correlazione, scatter plot e matrice di scatter plot.Correlazione e visualizzazione dei dati →. Esercizio: Esercizio - Statistica descrittiva, quartili e standardizzazione di un dataset.

Ambiente

  • Notebook (.ipynb) contro script (.py): il notebook alterna celle di codice e di testo, si esegue una cella alla volta e mostra subito i risultati (adatto a studio, esperimenti, analisi dati); lo script contiene solo codice, si esegue tutto insieme (programmi completi).
  • Google Colab: ambiente di esecuzione per notebook nel cloud: niente da installare, gratuito, buona potenza di calcolo. Si accede con l'account Google; i notebook si possono caricare o aprire da GitHub; i file si gestiscono dal pannello laterale (caricamento, salvataggio, download) e si può montare Google Drive.
  • Percorsi con pathlib.Path("ML_resources", "titanic.csv"); se i file non ci sono, nel laboratorio si clona il repository con git clone.

Linguaggio

  • Tipi e variabili: assegnazione senza dichiarare il tipo (x = 10 int, y = 3.14 float, z = "hello" str, w = True bool); type(x); divisione / (reale), // (intera), % resto, ** potenza; str * 3 ripete; i tipi diversi non si sommano (10 + "a" è un errore: convertire con str(x)).
  • Condizioni: if / elif / else, con and, or, not. L'indentazione è sintassi: niente graffe, i due punti, niente punto e virgola.
  • Cicli: for i in range(1, 6) (1, 2, 3, 4, 5: l'estremo finale è escluso) e while cond:.
  • Funzioni con def e return. I tipi immutabili (int, float, str, bool) sono passati per copia: una funzione che fa number = number + 10 non cambia la variabile del chiamante; per cambiarla bisogna restituire il valore e assegnarlo (x = add_ten(x)); una funzione senza return restituisce None.
  • Classi: raggruppano attributi (variabili) e metodi (funzioni) in modo riusabile; ogni cliente creato dalla classe è un oggetto. Nei laboratori si usano per modelli (fit, predict), nodi di alberi, criteri di impurità.
Struttura Ordinata Modificabile Duplicati Indicizzata
list [1, 2.5, "a"] sì sì sì sì
tuple (1, 2) sì no sì sì
set {1, 2} no sì no no
dict {"a": 1} no sì chiavi uniche per chiave

Gli indici partono da 00; lista[-1] è l'ultimo elemento; set(lista) dà gli elementi unici.

NumPy

python
import numpy as np
x = np.linspace(-3, 3, 1000)           # 1000 punti equispaziati
X = np.hstack([np.ones((n, 1)), X])    # aggiunge la colonna di uni a sinistra
beta = np.linalg.inv(X.T @ X) @ X.T @ y   # @ = prodotto tra matrici
np.mean(A, axis=0)                     # axis=0: una media per colonna; axis=1: per riga
A[A[:, 0] > 3]                         # maschera booleana: righe con prima colonna > 3
np.cumsum(v); np.argmax(v >= 5)        # somma cumulata; indice del primo valore >= 5
np.argsort(v)[::-1]                    # indici in ordine decrescente

Che cosa calcola la riga beta = ... (con i numeri). È la soluzione dei minimi quadratiQuando un sistema AX = b non ha soluzioni si cerca X che rende minima la norma di AX − b: AX è la proiezione ortogonale di b su Im A, e X si trova risolvendo le equazioni normali AᵀA X = Aᵀb; applicazione alla retta di regressione.Metodo dei minimi quadrati → della regressione lineare (Regressione lineareNell'apprendimento supervisionato si impara una funzione $F(x)$ dagli esempi $(x,y)$: regressione se $y$ è continua, classificazione se è categorica. Il modello lineare è $F_\beta(x)=\beta_0+\beta_1x_1+\dots+\beta_px_p=X\beta$ (con una colonna di uni per $\beta_0$) e i parametri si scelgono minimizzando l'errore quadratico medio $\mathrm{MSE}=\frac1n\sum_i(y_i-F_\beta(x_i))^2$, funzione convessa dei parametri. Annullando il gradiente di $J(\beta)=|y-X\beta|^2$ si ottengono le equazioni normali $X^TX\beta=X^Ty$ e la soluzione dei minimi quadrati ordinari $\beta=(X^TX)^{-1}X^Ty$. Il coefficiente di determinazione $R^2=1-SS_{res}/SS_{tot}$ misura la qualità del fit (0 = come la media, negativo = peggio della media). Un modello va valutato su un test set mai usato per addestrare: l'errore sul training è ottimistico e un polinomio di grado alto lo azzera senza generalizzare.Regressione lineare →). Si cerca β\beta che minimizza ∥y−Xβ∥2\lVert y-X\beta\rVert^2: il gradiente rispetto a β\beta (Differenziabilità e gradientef è differenziabile in x0 se f(x) = f(x0) + ∇f(x0)·(x − x0) + o(‖x − x0‖): vicino a x0 il grafico si confonde con il piano tangente z = f(x0) + ∇f(x0)·(x − x0). Differenziabile ⇒ continua, derivabile e D_v f = ∇f·v; derivate parziali continue ⇒ differenziabile. Il gradiente indica la direzione di massima crescita (pendenza ‖∇f‖) ed è ortogonale alle curve di livello.Differenziabilità e gradiente →) è −2XT(y−Xβ)-2X^T(y-X\beta) e si annulla quando XTXβ=XTyX^TX\beta=X^Ty (le equazioni normali); se XTXX^TX è invertibile (Matrice inversaL'inversa di una matrice quadrata A è la matrice A⁻¹ con A A⁻¹ = A⁻¹ A = I; esiste se e solo se rango(A) = n e si calcola con Gauss-Jordan riducendo (A | I) fino a (I | A⁻¹).Matrice inversa →) la soluzione è β=(XTX)−1XTy\beta=(X^TX)^{-1}X^Ty, che in NumPy si scrive esattamente come sopra, con @ per il prodotto riga per colonna (Operazioni tra matriciLe matrici m×n formano uno spazio vettoriale (somma e prodotto per scalare elemento per elemento); il prodotto righe per colonne corrisponde alla composizione di funzioni lineari, è associativo ma non commutativo; la trasposta scambia righe e colonne e (AB)^T = B^T A^T.Operazioni tra matrici →) e .T per la trasposta. Esempio con i tre appartamenti di Introduzione al machine learningIl machine learning (ML) è la parte dell'intelligenza artificiale che costruisce soluzioni a partire dai dati e non da regole scritte a mano: un modello matematico con parametri liberi viene addestrato su esempi storici e poi usato su dati nuovi. Si distingue tra apprendimento supervisionato (dati $(x,y)$, si impara la mappa $x\mapsto y$: regressione se $y$ è un numero, classificazione se è una categoria), non supervisionato (solo $x$, si cercano struttura e gruppi) e per rinforzo (stato, azione, ricompensa). Un progetto ML non è «plug and play»: segue le fasi problema, raccolta, pulizia, modellazione, rilascio, e va valutato su dati mai visti; senza dati non c'è modello, alcuni fenomeni sono imprevedibili, la generalizzazione fuori dal dominio di addestramento non è garantita.Introduzione al machine learning →: XX ha righe (1,50),(1,80),(1,100)(1,50),(1,80),(1,100) (la colonna di uni è il bias) e y=(160,205,260)y=(160,205,260). Allora XTX=(323023018900)X^TX=\begin{pmatrix}3&230\\230&18900\end{pmatrix} (somme di prodotti tra colonne: 1+1+1=31+1+1=3, 50+80+100=23050+80+100=230, 502+802+1002=1890050^2+80^2+100^2=18900), XTy=(625, 50400)X^Ty=(625,\,50400), determinante 3⋅18900−2302=38003\cdot18900-230^2=3800, e il risultato è β=(58,03; 1,9605)\beta=(58{,}03;\ 1{,}9605), i valori di intercetta e pendenza trovati nella nota introduttiva (verificato con np.linalg.inv). In pratica si preferisce np.linalg.lstsq o solve, numericamente più stabili dell'inversa esplicita.

pandas

python
import pandas as pd
df = pd.read_csv("ML_resources/titanic.csv")
df.head(); df.shape; df.columns          # prime righe, (righe, colonne), nomi
df["Sex"].value_counts()                 # conteggi per categoria
df["Age"].mean(); df["Age"].max()
df[df["Age"] > 30]["Sex"].value_counts() # filtro e conteggio
X = df.drop(columns=["target"]).to_numpy(); y = df["target"].to_numpy()

pandas è come un foglio di calcolo: filtra righe, aggrega statistiche, legge e scrive CSV. Le statistiche di pandas usano n−1n-1 (var, std), quelle di NumPy nn: per nn grande la differenza è trascurabile. Sul dataset Iris (150 righe, 5 colonne: 4 numeriche e la specie categorica) mean, var, std, skew, kurt, quantile(0.25) si calcolano sulle sole colonne numeriche, la moda sulla colonna categorica; corr() dà la matrice di correlazione di Pearson.

Grafici

Grafico interattivo: Il grafico di plt.plot(x, x**2) e plt.plot(x, np.sin(x)) con x = np.linspace(-3, 3, 1000): la parabola x² (pari) e il seno (dispari)

  • seaborn, costruita sopra Matplotlib, con interfaccia di più alto livello soprattutto per i DataFrame: sns.scatterplot(data=df, x=..., y=..., hue=...), sns.heatmap(corr, annot=True, cmap="coolwarm"), sns.pairplot(df), sns.boxplot, sns.violinplot, sns.barplot.
  • Per tabelle grandi si campiona (df.sample(1000)) prima del pair plot.

Trappole tipiche

Versione ripasso

Ambiente. Il notebook alterna celle di codice e testo e mostra subito i risultati; lo script contiene solo codice ed è eseguito tutto insieme. Google Colab esegue notebook nel cloud, gratis, con Drive montabile.

Linguaggio.

  • / è la divisione reale, // quella intera, % il resto, ** la potenza.
  • L'indentazione è sintassi. range(1, 6) esclude il 66.
  • I tipi immutabili (int, float, str, bool) sono passati per copia: una funzione deve fare return per cambiare un valore, e il chiamante deve assegnarlo.
  • Indici da 00; lista[-1] è l'ultimo elemento.
  • list (modificabile, con duplicati), tuple (immutabile), set (senza duplicati, non indicizzato), dict (per chiave).

NumPy.

  • axis=0 calcola una statistica per colonna, axis=1 per riga, senza axis su tutti gli elementi. Esempio. Con A=[[1,2],[3,4],[5,6]]A=[[1,2],[3,4],[5,6]]: A.mean(axis=0) =(3,4)=(3,4), A.mean(axis=1) =(1,5; 3,5; 5,5)=(1{,}5;\,3{,}5;\,5{,}5), A.mean() =3,5=3{,}5.
  • @ è il prodotto riga per colonna; .T la trasposta.
  • Forme. Un vettore (n,)(n,) non è una colonna (n,1)(n,1): con il broadcasting la differenza tra (3,)(3,) e (3,1)(3,1) dà una matrice 3×33\times3 senza errore. Si controlla con .reshape(-1, 1).
  • Varianza. np.var divide per nn, ddof=1 per n−1n-1. Esempio. Con [10,12,14,16,18][10,12,14,16,18] e somma degli scarti quadrati 4040: np.var dà 88, con ddof=1 si ha 1010.
  • np.cov e np.corrcoef vogliono le variabili sulle righe: con le osservazioni sulle righe serve rowvar=False.
  • Curtosi, asimmetria e moda non sono in NumPy.

Formula (minimi quadrati in NumPy). β=(XTX)−1XTy\beta=(X^TX)^{-1}X^Ty è la soluzione dei minimi quadratiQuando un sistema AX = b non ha soluzioni si cerca X che rende minima la norma di AX − b: AX è la proiezione ortogonale di b su Im A, e X si trova risolvendo le equazioni normali AᵀA X = Aᵀb; applicazione alla retta di regressione.Metodo dei minimi quadrati → (Regressione lineareNell'apprendimento supervisionato si impara una funzione $F(x)$ dagli esempi $(x,y)$: regressione se $y$ è continua, classificazione se è categorica. Il modello lineare è $F_\beta(x)=\beta_0+\beta_1x_1+\dots+\beta_px_p=X\beta$ (con una colonna di uni per $\beta_0$) e i parametri si scelgono minimizzando l'errore quadratico medio $\mathrm{MSE}=\frac1n\sum_i(y_i-F_\beta(x_i))^2$, funzione convessa dei parametri. Annullando il gradiente di $J(\beta)=|y-X\beta|^2$ si ottengono le equazioni normali $X^TX\beta=X^Ty$ e la soluzione dei minimi quadrati ordinari $\beta=(X^TX)^{-1}X^Ty$. Il coefficiente di determinazione $R^2=1-SS_{res}/SS_{tot}$ misura la qualità del fit (0 = come la media, negativo = peggio della media). Un modello va valutato su un test set mai usato per addestrare: l'errore sul training è ottimistico e un polinomio di grado alto lo azzera senza generalizzare.Regressione lineare →), con beta = np.linalg.inv(X.T @ X) @ X.T @ y.

Esempio (tre appartamenti). XX ha righe (1,50),(1,80),(1,100)(1,50),(1,80),(1,100) e y=(160,205,260)y=(160,205,260). Allora XTX=(323023018900)X^TX=\begin{pmatrix}3&230\\230&18900\end{pmatrix}, XTy=(625, 50400)X^Ty=(625,\,50400), determinante 38003800: β=(58,03; 1,9605)\beta=(58{,}03;\ 1{,}9605). In pratica si preferisce np.linalg.lstsq o solve, più stabili dell'inversa (Matrice inversaL'inversa di una matrice quadrata A è la matrice A⁻¹ con A A⁻¹ = A⁻¹ A = I; esiste se e solo se rango(A) = n e si calcola con Gauss-Jordan riducendo (A | I) fino a (I | A⁻¹).Matrice inversa →, Operazioni tra matriciLe matrici m×n formano uno spazio vettoriale (somma e prodotto per scalare elemento per elemento); il prodotto righe per colonne corrisponde alla composizione di funzioni lineari, è associativo ma non commutativo; la trasposta scambia righe e colonne e (AB)^T = B^T A^T.Operazioni tra matrici →).

pandas. È come un foglio di calcolo.

  • read_csv, head, shape (righe, colonne), columns.
  • value_counts per i conteggi di una categoria; filtri booleani come df[df["Age"] > 30].
  • mean, var, std, skew, kurt, quantile(0.25), corr: var e std usano n−1n-1; corr dà la correlazione di Pearson. Le statistiche si applicano alle sole colonne numeriche.

Grafici.

Errori tipici:

Esercizi su questo argomento

Teoria collegata