2016-04-26 8 views
4

Im folgenden Code erstelle ich einen Stichprobenumfang von 50, mit je 20 Merkmalen. Ich erzeuge dann einen zufälligen Zielvektor, der aus halben Wahren und Halben Falschen Werten besteht.Scikit-learn SVC gibt immer Genauigkeit 0 bei zufälliger Datenkreuzvalidierung

Alle Werte werden in Pandas-Objekten gespeichert, da dies ein echtes Szenario simuliert, in dem die Daten auf diese Weise ausgegeben werden.

Ich mache dann eine manuelle Leave-One-out innerhalb einer Schleife, jedes Mal wählen einen Index, löschen Sie die entsprechenden Daten, die restlichen Daten mit einem Standard SVC und schließlich eine Vorhersage auf der linken Seite ausgeführt Daten.

import random 
import numpy as np 
import pandas as pd 
from sklearn.svm import SVC 

n_samp = 50 
m_features = 20 

X_val = np.random.rand(n_samp, m_features) 
X = pd.DataFrame(X_val, index=range(n_samp)) 
# print X_val 

y_val = [True] * (n_samp/2) + [False] * (n_samp/2) 
random.shuffle(y_val) 
y = pd.Series(y_val, index=range(n_samp)) 
# print y_val 

seccess_count = 0 
for idx in y.index: 
    clf = SVC() # Can be inside or outside loop. Result is the same. 

    # Leave-one-out for the fitting phase 
    loo_X = X.drop(idx) 
    loo_y = y.drop(idx) 
    clf.fit(loo_X.values, loo_y.values) 

    # Make a prediction on the sample that was left out 
    pred_X = X.loc[idx:idx] 
    pred_result = clf.predict(pred_X.values) 
    print y.loc[idx], pred_result[0] # Actual value vs. predicted value - always opposite! 
    is_success = y.loc[idx] == pred_result[0] 
    seccess_count += 1 if is_success else 0 

print '\nSeccess Count:', seccess_count # Almost always 0! 

Jetzt ist hier der seltsame Teil - ich erwarte, dass eine Genauigkeit von etwa 50% erhalten, da diese Zufallsdaten ist, sondern fast immer genau 0 ich! Ich sage fast immer, da alle etwa 10 Läufe dieses genauen Codes bekomme ich ein paar richtige Treffer.

Was ist wirklich verrückt nach mir ist, dass, wenn ich die Antworten entgegengesetzt zu denen vorausgesagt, werde ich 100% Genauigkeit erhalten. Auf zufällige Daten!

Was fehlt mir hier?

Antwort

4

Ok, ich denke, ich habe es gerade herausgefunden! Es kommt alles auf unseren alten Gegner des maschinellen Lernens an - die Mehrheitsklasse.

Ausführlicher: Ich wählte ein Ziel aus 25 True und 25 False-Werten - perfekt ausbalanciert. Beim Ausführen des Leave-One-Outs führte dies zu einem Klassenungleichgewicht, sagen wir 24 True und 25 False. Da der SVC auf Standardparameter eingestellt war und auf zufälligen Daten ausgeführt wurde, konnte er wahrscheinlich keine andere Möglichkeit finden, das Ergebnis vorherzusagen, als die Mehrheitsklasse zu wählen, die in dieser Iteration False wäre! So wurde das Ungleichgewicht in jeder Iteration gegen die derzeit ausgelassene Stichprobe gewendet.

Alles in allem - eine gute Lektion in maschinellem Lernen, und ein hervorragendes mathematisches Rätsel mit deinen Freunden zu teilen :)

+1

Nizza Fang! Das erklärt, warum ich das Problem nicht neu erstellen konnte, als ich den Zielvektor mit 'y_val = np.random.rand (50) <0.5 'erstellte. –

+0

Du hast mich gerettet! –