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?
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
geschichtete Stichproben haben die Ausgabe nicht durch viel verbessert – suku
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