Machine Learning + Hyperparameter Tuning + Data Leakage: la mia procedura è priva di perdite di dati?
Sto cercando di classificare 8 tipi di gesti delle mani con segnali EMG. Per questo ho seguito questi passaggi:
- Dividi tutti i dati in dati di addestramento e dati di test
- Per i dati di addestramento ho estratto le caratteristiche. Ecco come l'ho fatto: il set di dati di addestramento contiene 8 file. Ogni file è composto da 50 letture del bracciale Myo per un gesto definito. Ogni lettura include 100 campioni per sensore. Ci sono 8 sensori. Per ogni 100 campioni/sensore, viene calcolata la media (di) valori assoluti (MAV). Per 8 sensori, vengono calcolati 8 MAVS per una lettura. Quindi ogni riga contiene 8 valori MAV per un particolare gesto. Ecco un sottoinsieme di dati di allenamento (l'ultima colonna è il rispettivo numero di gesto):


Successivamente ho provato a testare diversi modelli di ensemble come classificatori sui dati di addestramento. Ad esempio, ho provato a utilizzare lo stack di Random Forest, KNN, SVM sui dati di addestramento. Per questo ho usato GridSearchCV per l'ottimizzazione degli iperparametri (non ho usato pipelie). Ecco il codice:
param_grid = [
{ #Random forest 'bootstrap': [True, False], 'max_depth': [40, 50, 60, 70, 80], #'max_features': [2, 3], 'min_samples_leaf': [3, 4, 5], 'min_samples_split': [8, 10, 12], 'n_estimators': [10, 15, 20, 25], 'criterion' : ['gini', 'entropy'], 'random_state' : [45] }, { #K Nearest Neighbours 'n_neighbors':[5,6,7,9,11], 'leaf_size':[1,3,5,7], 'algorithm':['auto', 'ball_tree', 'kd_tree', 'brute'], 'metric':['euclidean', 'manhattan'] }, { #SVM 'C': list(np.arange(1, 5, 0.01)), 'gamma': ['scale', 'auto'], 'kernel': ['rbf', 'poly', 'sigmoid', 'linear'], 'decision_function_shape': ['ovo', 'ovr'], 'random_state' : [45] } ] models_to_train = [RandomForestClassifier(), KNeighborsClassifier(), svm.SVC()] final_models = [] for i, model in enumerate(models_to_train): params = param_grid[i] clf = GridSearchCV(estimator=model, param_grid=params, cv=20, scoring = 'accuracy').fit(data_train, label_train) final_models.append(clf.best_estimator_)
Ha eseguito una procedura di estrazione delle caratteristiche simile al passaggio 2 per i dati di test
Adatta il modello in pila ai dati di addestramento, ha fatto previsioni sui dati di test e ha calcolato l'accuratezza.
estimators = [ ('rf', final_models[0]), ('knn', final_models[1]) ] clf = StackingClassifier( estimators=estimators, final_estimator=final_models[2] ) category_predicted = clf.fit(data_train, label_train).predict(data_test) acc = accuracy_score(label_test, category_predicted) * 100
Ora, la mia domanda è,
C'è qualche possibilità di perdita di dati in questa procedura?
Modificare
Credo che questa procedura soffra di perdita di dati perché ho eseguito l'estrazione delle funzionalità nel passaggio 2 su interi dati di addestramento e tali funzionalità sono utilizzate GridSearchCV
senza alcun file pipeline
. Se inserisco l'estrazione delle caratteristiche (come descritto nel passaggio 2) e lo stimatore pipeline
(come discusso qui:https://towardsdatascience.com/pre-process-data-with-pipeline-to-prevent-data-leakage-during-cross-validation-e3442cca7fdc), quindi può essere evitato.
Risposte
Un problema potenzialmente più grande della perdita di dati tra test e set di addestramento è l'inaffidabilità delle divisioni test/train di piccoli set di dati. Hai bisogno di molte migliaia di casi affinché sia affidabile. Altrimenti stai buttando via le informazioni limitando la dimensione del set di addestramento e stai ottenendo stime imprecise della validità del modello avendo un set di test troppo piccolo.
Poiché disponi di un algoritmo ben definito per la creazione del tuo modello, considera invece la convalida interna tramite bootstrap. Questa risposta delinea la procedura. Anche se continui a utilizzare una suddivisione train/test per la tua modellazione, la ripetizione dell'intero processo di modellazione, inclusa la suddivisione train/test originale su più campioni bootstrap dei tuoi dati, valuterà la quantità di un problema imposto da qualsiasi perdita di dati.
Nel tuo caso non sembra che tu abbia un problema con la perdita di dati nella tua convalida incrociata. Tutto quello che hai fatto è combinare le letture grezze in un tipo di media, il MAV, senza alcun tentativo di standardizzare le letture all'interno di ciascun sensore in quel punto dell'analisi . Potrebbe esserci una certa standardizzazione in seguito all'interno della ricerca dei parametri, ma per quanto ne so (non sono fluente in sklearn
) sembra essere fatto in modo appropriato.
È diverso dalla situazione descritta nella pagina che colleghi . Lì ciascuno dei predittori è stato standardizzato fin dall'inizio per metterli sulla stessa scala relativa, come è necessario per le analisi delle componenti principali e le regressioni penalizzate (cresta, LASSO). Poiché il grado di trasformazione di qualsiasi predittore necessario per la standardizzazione varierà da campione a campione, questo può essere un problema se il tuo (saggio) intento è ripetere l' intero processo di modellazione (inclusa la standardizzazione) in ogni piega CV o campione bootstrap. Non hai fornito i dati pre-standardizzati della tua ricerca dei parametri, solo una media senza alcun cambiamento di scala, quindi non dovresti avere questo problema.