У меня есть набор данных, который я использовал для создания модели NN в Керасе, я взял 2000 строк из этого набора данных, чтобы иметь их в качестве проверочных данных, эти 2000 строк должны быть добавлены в функцию .predict
.
I написал код для Keras NN и пока он работает хорошо, но я заметил кое-что, что очень странно для меня. Это дает мне очень хорошую точность - более 83%, потери - около 0,12, но когда я хочу сделать прогноз с помощью невидимых данных (эти 2000 строк), он дает только правильный прогноз в среднем на 65%. Когда я добавляю слой Dropout, он только снижает точность.
Затем я добавил EarlyStopping
, и это дало мне точность около 86%, потери - около 0,10, но все же, когда я делаю прогноз с невидимыми данными, я получить окончательную точность прогноза 67%.
Означает ли это, что модель сделала правильный прогноз в 87% ситуаций? Я собираюсь с логикой c, если я добавлю 100 выборок в мою функцию .predict
, эта программа должна сделать хороший прогноз для 87/100 выборок или где-то в этом диапазоне (скажем, более 80)? Я попытался добавить 100, 500, 1000, 1500 и 2000 сэмплов в мою функцию .predict
, и она всегда дает правильный прогноз в 65-68% выборок.
Почему это так, я делаю что-то не так? Я попытался поиграть с количеством слоев, количеством узлов, с разными функциями активации и с разными оптимизаторами, но результаты меняются только на 1-2%. Мой набор данных выглядит следующим образом:
DataFrame shape (59249, 33)
x_train shape (47399, 32)
y_train shape (47399,)
x_test shape (11850, 32)
y_test shape (11850,)
testing_features shape (1000, 32)
Это моя модель NN:
model = Sequential()
model.add(Dense(64, input_dim = x_train.shape[1], activation = 'relu')) # input layer requires input_dim param
model.add(Dropout(0.2))
model.add(Dense(32, activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(16, activation = 'relu'))
model.add(Dense(1, activation='sigmoid')) # sigmoid instead of relu for final probability between 0 and 1
# compile the model, adam gradient descent (optimized)
model.compile(loss="binary_crossentropy", optimizer= "adam", metrics=['accuracy'])
# call the function to fit to the data training the network)
es = EarlyStopping(monitor='val_loss', min_delta=0.0, patience=1, verbose=0, mode='auto')
model.fit(x_train, y_train, epochs = 15, shuffle = True, batch_size=32, validation_data=(x_test, y_test), verbose=2, callbacks=[es])
scores = model.evaluate(x_test, y_test)
print(model.metrics_names[0], round(scores[0]*100,2), model.metrics_names[1], round(scores[1]*100,2))
Вот результаты:
Train on 47399 samples, validate on 11850 samples
Epoch 1/15
- 25s - loss: 0.3648 - acc: 0.8451 - val_loss: 0.2825 - val_acc: 0.8756
Epoch 2/15
- 9s - loss: 0.2949 - acc: 0.8689 - val_loss: 0.2566 - val_acc: 0.8797
Epoch 3/15
- 9s - loss: 0.2741 - acc: 0.8773 - val_loss: 0.2468 - val_acc: 0.8849
Epoch 4/15
- 9s - loss: 0.2626 - acc: 0.8816 - val_loss: 0.2416 - val_acc: 0.8845
Epoch 5/15
- 10s - loss: 0.2566 - acc: 0.8827 - val_loss: 0.2401 - val_acc: 0.8867
Epoch 6/15
- 8s - loss: 0.2503 - acc: 0.8858 - val_loss: 0.2364 - val_acc: 0.8893
Epoch 7/15
- 9s - loss: 0.2480 - acc: 0.8873 - val_loss: 0.2321 - val_acc: 0.8895
Epoch 8/15
- 9s - loss: 0.2450 - acc: 0.8886 - val_loss: 0.2357 - val_acc: 0.8888
11850/11850 [==============================] - 2s 173us/step
loss 23.57 acc 88.88
И это для прогноза:
#testing_features are 2000 rows that i extracted from dataset (these samples are not used in training, this is separate dataset thats imported)
prediction = model.predict(testing_features , batch_size=32)
res = []
for p in prediction:
res.append(p[0].round(0))
# Accuracy with sklearn - also much lower
acc_score = accuracy_score(testing_results, res)
print("Sklearn acc", acc_score)
result_df = pd.DataFrame({"label":testing_results,
"prediction":res})
result_df["prediction"] = result_df["prediction"].astype(int)
s = 0
for x,y in zip(result_df["label"], result_df["prediction"]):
if x == y:
s+=1
print(s,"/",len(result_df))
acc = s*100/len(result_df)
print('TOTAL ACC:', round(acc,2))
Проблема в том ... теперь я получаю точность со склеарном 52% и my_acc
52%. Почему я получаю такую низкую точность при проверке, когда говорится, что она намного больше?