Hyperparameter Optimization: Grid Search vs Random Search

In questo articolo vediamo cosa si intende per Hyperparameter Optimization e la differenza tra le sue due principali tecniche: Grid Search e Random Search.

Hyperparameter Optimization, Grid Search, Random Search…

A prima vista sono parole che possono spaventare, ma così non deve essere. Si tratta infatti di concetti non troppo difficili, che un po’ di introduzione e spiegazione possiamo comprendere e utilizzare per migliorare i nostri modelli di Machine Learning. Concetti molto potenti e molto importanti, ma spesso molto fraintesi. Cerchiamo allora di fare un po’ di chiarezza, mettendo in luce due tra le tecniche più in uso in questo ambito.

Naturalmente la nostra non sarà una trattazione esaustiva, ma si concentrerà sulle due tecniche principali di hyperparameter optimization.

INDICE

  • Hyperparameter Optimization
  • Grid Search
  • Random Search
  • Differenze, pro e contro
  • Conclusioni

Hyperparameter Optimization

L’hyperparameter optimization, o tuning degli iperparametri, è l’ambito che si occupa della scelta dei parametri ottimali per un modello di Machine Learning. Ogni modello di Machine Learning utilizza infatti dei parametri che l’analista può modificare per migliorare le sue performances.

Solitamente quando si va ad implementare un algoritmo di Machine Learning, viene messo a disposizione un pre-set di iperparametri. Non fare tuning quindi vuol dire lasciare il mondo così com’è e utilizzare quei parametri.

Naturalmente, sebbene lasciare il mondo come sta non comporti un errore, usare i parametri di default non è spesso la soluzione migliore. Potrebbe convenire usare un certo tipo di valore per degli iperparametri, diversi probabilmente da quelli di default.

Prendiamo il caso di uno degli algoritmi più semplici, ovvero l’Albero Decisionale (o Decision Tree). Se andiamo sulla sua pagina dedicata della libreria scikit-learn (ne parliamo qui) vediamo quali sono i suoi iperaparametri di default e come li possiamo modificare.

class sklearn.tree.DecisionTreeClassifier(*criterion=’gini’splitter=’best’max_depth=Nonemin_samples_split=2min_samples_leaf=1min_weight_fraction_leaf=0.0max_features=Nonerandom_state=Nonemax_leaf_nodes=Nonemin_impurity_decrease=0.0min_impurity_split=Noneclass_weight=Noneccp_alpha=0.0)

Ho messo in grassetto i nomi degli iperparametri, alla destra dell’uguale troviamo il valore impostato di default. Lanciare il modello così com’è vorrà dire utilizzare i parametri di default.

Questa potrebbe anche essere la scelta giusta in alcuni casi, ma per esperienza diretta posso dire che quasi mai questi valori portano a risultati soddisfacenti.

Una dei principali problemi del Decision Tree, per esempio, è quello di cadere in Overfitting, ovvero non saper bene generalizzare con dati nuovi. Un modello standard di Decision Tree cadrà sempre in overfitting, perché gli iperparametri che si occupano spesso di prevenirlo, come per esempio max_depth, min_samples_leaf e max_features, non sono valorizzati in modo da ostacolarlo.

Cambiare quindi questi parametri, combinarli tra loro e vedere i risultati, è quello che intendiamo per hyperparameter optimization. Trovare il set ideale (nel nostro caso) di iperapametri.

Come farlo… in modo efficiente?

Naturalmente potrei cambiare i parametri ad uno ad uno e vedere come cambiano le performances, ma questa è una procedura che risulterebbe lenta e macchinosa, e poco efficiente. Esistono invece molte tecniche per ottimizzare la scelta degli iperparametri, tecniche in qualche modo automatiche. In questo articolo ne vedremo principalmente due, ovvero la Grid Search e la Random Search.

Grid Search

La prima tecnica di tuning di iperparametri che vediamo si chiama Grid Search, la più tradizionale per il tuning.

Si tratta di inserire un insieme di valori per i parametri che vogliamo ottimizzare e provare tutte le possibili combinazioni. Un modello per ogni combinazione.

Riprendiamo il caso del DecisionTree che abbiamo visto prima.

Nella documentazione vediamo che il primo parametro preso in considerazione, “criterion“, ha come valore di default “gini”. Questo parametro misura la qualità dello split e accetta due possibili valori: “gini” e “entropy”, l’entropia. Posso così dire al modello: addestrati con criterion = “gini” e con criterion = “entropy”, poi valuta i risultati e prendi il valore dell’iperparametro che ha portato al modello migliore.

E se volessi combinare più parametri insieme?

Immaginiamo di voler provare:

criterion = [“gini”, “entropy”]
max_depth = [3,4,5,6]
max_features = [None, 0.5]
min_samples_leaf = [1,25,50]

In questo caso la Grid Search farà un modello per ognuna delle possibili combinazioni di queste parametri. Vorrà dire che proverà criterion = “gini” con max_depth = 3, max_features = None, min_samples_leaf 1, poi criterio = “entropy” e max_depth = 3, max_features = None, min_samples_leaf 1 ecc ecc.

Inseriamo quindi una griglia di valori per ogni iperparametro che vogliamo ottimizzare e proviamo tutti i possibili modelli con tutte le possibili combinazioni dei parametri inseriti.

Random Search

La Grid Search cercherà tra tutti i valori possibili la miglior combinazione per il modello migliore. All’aumentare però dei valori che voglio provare, aumenterà in modo esponenziale il numero di modelli da provare e quindi il tempo che il mio algoritmo impiegherà per il miglior risultato.

Un’alternativa molto valida è quella della Random Search. In questa tecnica rimpiazziamo l’esaustiva enumerazione di tutte le combinazioni con un certo numero di randomiche combinazioni.

Siamo noi a scegliere il numero di combinazioni da provare, e in base a questo numero la Random Search andrà a pescare a caso un valore del nostro set di valori per ogni iperparametro. Addestrà un modello con queste combinazioni e lo valuterà, scegliendo poi il modello con la combinazione di iperparametri.

Riprendiamo il caso di prima:

criterion = [“gini”, “entropy”]
max_depth = [3,4,5,6]
max_features = [None, 0.5]
min_samples_leaf = [1,25,50]

Al posto di testare tutte le possibili combinazioni di questi parametri, ne andrà a prendere per esempio 10 tra tutte le possibili combinazioni. Questo naturalmente abbatterà i tempi di addestramento, sebbene comporti una minore possibilità di beccare la combinazione giusta. Chi ci assicura infatti che in queste 10 combinazioni ci sia la più performante?

Differenze, pro e contro

Grid Search: prova tutte le possibili combinazioni dei valori che do per ogni iperparametro.

Random Search: prende randomicamente un sottoinsieme delle possibili combinazioni dei valori che do per ogni iperparametro.

La Grid Search è più precisa perché, provando tutte le possibili combinazioni di valori per ogni iperparametro, troverà sicuramente la performante. Allo stesso tempo però, dovendo addestrare un modello per ognuna di queste combinazioni, impiegherà molto tempo, soprattutto all’aumentare dei parametri e dei valori che voglio provare.

Al contrario, la Random Search sarà meno precisa perché nella selezione randomica non è detto che capiti la miglior combinazione, però ha un tempo di esecuzioni molto minore e permette comunque una buona accuratezza dei risultati.

Conclusioni

Nell’articolo di oggi abbiamo parlato di Hyperparameter Optimization e abbiamo visto due tra le tecniche più diffuse per migliorare i modelli.

Naturalmente esistono molte altre tecniche, ma abbiamo deciso (per ora…) di soffermarci su queste due!