У меня есть набор данных, который выглядит так:
df.head(5)
data labels
0 [0.0009808844009380855, 0.0008974465127279559] 1
1 [0.0007158940267629654, 0.0008202958833774329] 3
2 [0.00040971929722210984, 0.000393972522972382] 3
3 [7.916243163372941e-05, 7.401835468434177e243] 3
4 [8.447556379936086e-05, 8.600626393842705e-05] 3
Столбец «данные» - это мой X, а метки - это y. В df 34890 строк. В каждом ряду по 2 поплавка. Данные представляют собой связку последовательного текста, и каждое наблюдение является представлением предложения. Всего 5 классов.
Я тренирую его на этом LSTM-коде:
data = df.data.values
labels = pd.get_dummies(df['labels']).values
X_train, X_test, y_train, y_test = train_test_split(data,labels, test_size = 0.10, random_state = 42)
X_train = X_train.reshape((X_train.shape[0],1,X_train.shape[1])) # shape = (31401, 1, 5)
X_test = X_test.reshape((X_test.shape[0],1,X_test.shape[1])) # shape = (3489, 1, 5)
### y_train shape = (31401, 5)
### y_test shape = (3489, 5)
### Bi_LSTM
Bi_LSTM = Sequential()
Bi_LSTM.add(layers.Bidirectional(layers.LSTM(32)))
Bi_LSTM.add(layers.Dropout(.5))
# Bi_LSTM.add(layers.Flatten())
Bi_LSTM.add(Dense(11, activation='softmax'))
def compile_and_fit(history):
history.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
history = history.fit(X_train,
y_train,
epochs=30,
batch_size=32,
validation_data=(X_test, y_test))
return history
LSTM_history = compile_and_fit(Bi_LSTM)
Модель обучается, но точность val фиксирована на уровне 53% для каждой эпохи. Я предполагаю, что это из-за моей проблемы с дисбалансом классов (1 класс занимает ~ 53% данных, остальные 4 в некоторой степени равномерно распределены по оставшимся 47%).
Как мне сбалансировать мои данные? Мне известны типичные методы избыточной / недостаточной выборки для данных, не относящихся к временным рядам, но я не могу использовать избыточную / недостаточную выборку, потому что это нарушит характер данных с последовательными временными рядами. Любой совет?
EDIT
Я пытаюсь использовать аргумент class_weight в Keras для решения этой проблемы. Я передаю этот dict в аргумент class_weight:
class_weights = {
0: 1/len(df[df.label == 1]),
1: 1/len(df[df.label == 2]),
2: 1/len(df[df.label == 3]),
3: 1/len(df[df.label == 4]),
4: 1/len(df[df.label == 5]),
}
На чем я основываюсь на этой рекомендации:
https://stats.stackexchange.com/questions/342170/how-to-train-an-lstm-when-the-sequence-has-imbalanced-classes
Однако , акк / проигрыш сейчас действительно ужасный. Я получаю ~ 30% точности с плотным net, поэтому я ожидал, что LSTM будет улучшением. См. Кривые увеличения / уменьшения ниже: