2016-01-02 15 views
5

Sto provando a eseguire la classificazione multilabel con SVM. Ho quasi 8k e ho anche un vettore di lunghezza con quasi 400. Ho già vettori Y binarizzati, quindi non ho usato MultiLabelBinarizer() ma quando lo uso con il modulo raw dei miei dati Y, restituisce sempre la stessa cosa.Scikit-Learn: Label not x è presente in tutti gli esempi di formazione

Io corro questo codice:

X = np.genfromtxt('data_X', delimiter=";") 
Y = np.genfromtxt('data_y', delimiter=";") 
training_X = X[:2600,:] 
training_y = Y[:2600,:] 

test_sample = X[2600:2601,:] 
test_result = Y[2600:2601,:] 

classif = OneVsRestClassifier(SVC(kernel='rbf')) 
classif.fit(training_X, training_y) 
print(classif.predict(test_sample)) 
print(test_result) 

Dopo tutto attacco di processo quando si tratta di una parte di previsione, si dice Label not x is present in all training examples (x è un paio di numeri diversi nella gamma della mia y lunghezza del vettore, che è 400) . Dopodiché fornisce un vettore y previsto che è sempre un vettore zero con una lunghezza di 400 (lunghezza del vettore y). Sono nuovo in scikit-learn e anche in machine learning. Non sono riuscito a capire il problema qui. Qual è il problema e cosa dovrei fare per risolverlo? Grazie.

risposta

10

Ci sono 2 problemi qui:

1) L'etichetta mancante avvertimento
2) Hai trovato tutti i 0 di per le previsioni

L'avviso indica che alcune delle classi mancano dai dati di addestramento. Questo è un problema comune. Se hai 400 classi, alcune di esse devono verificarsi solo molto raramente, e su qualsiasi suddivisione dei dati, alcune classi potrebbero mancare da un lato della divisione. Potrebbero esserci anche classi che semplicemente non si verificano nei tuoi dati. Potresti provare Y.sum(axis=0).all() e se è False, alcune classi non si verificano nemmeno in Y. Tutto ciò sembra orribile, ma realisticamente, non sarai in grado di prevedere correttamente le classi che si verificano 0, 1 o qualsiasi molto piccola numero di volte comunque, quindi prevedere 0 per quelli è probabilmente il meglio che puoi fare.

Per quanto riguarda le previsioni tutto-0, farò notare che con 400 classi, probabilmente tutte le classi si verificano molto meno della metà del tempo. È possibile controllare Y.mean(axis=0).max() per ottenere la frequenza più alta dell'etichetta. Con 400 classi, potrebbe essere solo una piccola percentuale. Se è così, un classificatore binario che deve fare una previsione 0-1 per ogni classe probabilmente sceglierà 0 per tutte le classi su tutte le istanze. Questo non è proprio un errore, è solo perché tutte le frequenze delle classi sono basse.

Se si sa che ogni istanza ha un'etichetta positiva (almeno una), è possibile ottenere i valori di decisione (clf.decision_function) e selezionare la classe con la più alta per ogni istanza. Dovrai scrivere un codice per farlo, però.

Una volta ho avuto una vittoria in top-10 in un contest di Kaggle simile a questo. Era un problema multilabel con ~ 200 classi, nessuna delle quali si verificava con una frequenza del 10% e avevamo bisogno di previsioni 0-1. In quel caso ho preso i valori decisionali e ho preso quello più alto, oltre a tutto ciò che era al di sopra di una soglia. Ho scelto la soglia che ha funzionato al meglio su un set di holdout. Il codice per quella voce è su Github: Kaggle Greek Media code. Potresti dare un'occhiata a questo.

Se sei arrivato così lontano, grazie per la lettura. Spero possa aiutare.

+1

Ciao, grazie per una risposta con molte cose utili. Ho provato 'Y.sum (axis = 0) .all()' e ha restituito True. Inoltre, ho provato 'Y.mean (axis = 0) .max()' e ha restituito '0.315981070258'. Devo ancora implementare un 'clf.decision_function'? Puoi essere più specifico a riguardo, come implementarlo e così? Mi dispiace, sono molto nuovo in queste cose, quindi non potevo capire cosa fare con 'decision_function'. – malisit

+1

Sto dicendo che se stai ricevendo tutti i pronostici zero e sai che ci dovrebbero essere alcuni 1 in là, potresti provare a ottenere valori decisionali invece, e prevedere 1 ogni volta che è al di sopra di qualche soglia.Le tue etichette previste sarebbero: '(valore_corsa> soglia) .astipo (float)'. La soglia sarà inferiore a 0, poiché 0 è la soglia utilizzata dal classificatore e non riceve alcun risultato positivo. In alternativa, se sai che esiste almeno un'etichetta positiva per istanza, puoi scegliere l'etichetta con il DV più alto (sarà comunque negativo). – Dthal

+0

Grazie! L'intuizione e il codice che hai fornito su GitHub hanno davvero aiutato. – malisit