2017-06-10 3 views
0

Ich habe einen unausgeglichenen Datensatz von 2 Klassen (1 & 0). 1 ist etwa 6 mal weniger wahrscheinlich als 0. Daher verwende ich SMOTE, um den Datensatz durch Überabtastung auszugleichen. Die Verwendung von SMOTE führt zu einem extrem verzerrten Ergebnis. Ich kann nicht verstehen, warumTensorflow: Oversampling mit SMOTE mit stark verzerrten Ergebnissen

from imblearn.over_sampling import SMOTE 

def train_neural_network(x, y, features, labels): 

    X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2) 

    print(len(y_train), len(y_train[y_train == 1]), len(y_train[y_train == 0])) 

    sm = SMOTE() 
    X_train, y_train = sm.fit_sample(X_train, y_train) 

    print(len(y_train), len(y_train[y_train == 1]), len(y_train[y_train == 0])) 

    prediction = neural_network_model(x, len(features.columns)) 
    cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=prediction, labels=tf.cast(y, tf.int32))) 
    optimizer = tf.train.AdamOptimizer().minimize(cost) 

    hm_epochs = 1 

    with tf.Session() as sess: 
    sess.run(tf.initialize_all_variables()) 
    for epoch in range(hm_epochs): 
     epoch_loss = 0 

     for i in range(int(len(X_train)/batch_size)): 
      epoch_x = X_train[i*batch_size: min((i + 1)*batch_size, len(X_train))] 
      epoch_y = y_train[i*batch_size: min((i + 1)*batch_size, len(y_train))] 
      i, c = sess.run([optimizer, cost], feed_dict = {x:epoch_x, y:epoch_y}) 
      epoch_loss += c 

     print('Epoch', epoch + 1, ' completed out of ', hm_epochs, ' loss: ', epoch_loss) 

    correct = tf.equal(tf.argmax(prediction, 1), y) 

    accuracy = tf.reduce_mean(tf.cast(correct, tf.float32)) 

    print('Accuracy : ', sess.run(accuracy, feed_dict={x: X_test, y: y_test})) 

    y1 = y_test[y_test == 1] 
    X1 = X_test[y_test == 1] 
    print('Accuracy 1: ', sess.run(accuracy, feed_dict={x: X1, y: y1})) 

    y0 = y_test[y_test == 0] 
    X0 = X_test[y_test == 0] 
    print('Accuracy 0: ', sess.run(accuracy, feed_dict={x: X0, y: y0})) 


with open("xdf.pickle", 'rb') as f: 
    features = pickle.load(f) 
with open("ydf.pickle", 'rb') as f: 
    labels = pickle.load(f) 
x = tf.placeholder('float', [None, len(features.columns)]) 
y = tf.placeholder(tf.int64) 
train_neural_network(x, y, features, labels) 

Dies ist der Ausgang (print-Anweisungen) ist

1521207 255174 1266033 // initial dataset (total points, label = 1, label = 0) 
2532066 1266033 1266033 // after smote 
Epoch 1 completed out of 1 loss: 345947.933431 // after 1 epoch 
Accuracy : 0.168227 // test accuracy 
Accuracy 1: 1.0 // output of test with all labels = 1 
Accuracy 0: 3.1613e-06 // output of test will all labels = 0 

Wenn ich den Datensatz nicht über habe Probe dann ich folgendes Ergebnis

1521207 255174 1266033 // initial dataset (total points, label = 1, label = 0) 
Epoch 1 completed out of 1 loss: 270053.921566 // after 1 epoch 
Accuracy : 0.762063 // test accuracy 
Accuracy 1: 0.1554 // output of test with all labels = 1 
Accuracy 0: 0.883916 // output of test will all labels = 0 

erhalten diese gibt eine erwartete Ausgabe, wenn der Datensatz verzerrt ist. Mache ich einen Fehler bei der Verwendung von SMOTE? Warum wird das Ergebnis so verzerrt?

Antwort

0

Können Sie hier eine geschichtete Probenahme versuchen? Da Sie Ihren Diagrammcode nicht eingefügt haben, kann ich den Typ der Aufgabe hier außer dem Klassifizierungstyp nicht erraten. Es könnte sich um sequenzielle Daten handeln, in welchem ​​Fall wir solche Ergebnisse sehen könnten.

Ich sehe, dass es einige zeitliche Natur in den Daten gibt. SMOTE fügt unnötig mehr unerwünschte Indikatoren in die Daten ein. Bitte versuchen Sie hier die gewichtete Verlustfunktion, bei der Sie den dominanten Klassenfehler um sein Ausführlichkeitsverhältnis gegenüber den anderen Bezeichnungen abmildern.

Auch für sehr seltene Ereignisse können Trainingsklassifikatoren, die für verschiedene seltene Labels voreingenommen sind und die Ensemble-Methode mit Voting verwenden, hilfreich sein.

+0

Ich möchte eine Klassifizierung. Im Grunde genommen sind die Merkmale Börsenindikatorwerte und das Kennzeichen ist, ob die Aktie in den nächsten 20 Tagen um 10% gestiegen ist. Also möchte ich sehen, welche Indikatorwerte in Kombination den Vorrat vorhersagen können. – suku

+0

geschichtete Stichproben haben die Ausgabe nicht durch viel verbessert – suku

+0

Ich sehe, dass es einige zeitliche Natur in den Daten gibt. SMOTE fügt unnötig mehr unerwünschte Indikatoren in die Daten ein. Können Sie hier eine gewichtete Verlustfunktion ausprobieren, bei der Sie den dominanten Klassenfehler um sein Ausführlichkeitsverhältnis gegenüber den anderen Bezeichnungen abmildern. (Ich denke, in Ihrem Fall sind die meisten Daten, die häufig vorkommen, diejenigen, die den Bestand in keiner Weise erhöhen. Habe ich Recht?) – Sunny

Verwandte Themen