为什么我的神经网络只能预测一个类别(二进制分类)?

时间:2019-07-01 19:33:39

标签: python tensorflow keras neural-network

我的人工神经网络遇到了一些麻烦。它只是预测为“ 0”。数据集不平衡(10:1),尽管如此,我对训练数据集采样不足,所以我不确定发生了什么。我在平衡训练集上获得了92-93%的准确性,尽管在测试中(在非平衡测试集上)它只能预测零。不确定从这里去哪里。任何帮助。数据已经过一次热编码和缩放。

#create 80/20 train-test split
train, test = train_test_split(selection, test_size=0.2)

# Class count
count_class_0, count_class_1 = train.AUDITED_FLAG.value_counts()

# Divide by class
df_class_0 = train[train['AUDITED_FLAG'] == 0]
df_class_1 = train[train['AUDITED_FLAG'] == 1]

df_class_0_under = df_class_0.sample(count_class_1)
train_under = pd.concat([df_class_0_under, df_class_1], axis=0)

print('Random under-sampling:')
print(train_under.AUDITED_FLAG.value_counts())

train_under.AUDITED_FLAG.value_counts().plot(kind='bar', title='Count (target)');

Random under-sampling:
1.0    112384
0.0    112384

#split features and labels 
y_train = np.array(train_under['AUDITED_FLAG'])
X_train = train_under.drop('AUDITED_FLAG', axis=1)
y_test = np.array(test['AUDITED_FLAG'])
X_test = test.drop('AUDITED_FLAG', axis=1)
y_train = y_train.astype(int)
y_test = y_test.astype(int)


# define model
model = Sequential()
model.add(Dense(6, input_dim=179, activation='relu'))
model.add(Dense(30, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# fit model
history = model.fit(X_train, y_train, epochs=5, batch_size=16, verbose=1)

#validate
test_loss, test_acc = model.evaluate(X_test, y_test)

# evaluate the model
_, train_acc = model.evaluate(X_train, y_train, verbose=0)
_, test_acc = model.evaluate(X_test, y_test, verbose=0)

print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
print('test_acc:', test_acc)

# plot history
pyplot.plot(history.history['acc'], label='train')
#pyplot.plot(history.history['val_acc'], label='test')

火车:0.931,测试:0.921

#preds
y_pred = model.predict(X_test)
y_pred_bool = np.argmax(y_pred, axis=1)

# #plot confusion matrix 
y_actu = pd.Series(y_test, name='Actual')
y_pred_bool = pd.Series(y_pred_bool, name='Predicted')

print(pd.crosstab(y_actu, y_pred_bool))

'''

Predicted       0
Actual           
0           300011
1            28030

1 个答案:

答案 0 :(得分:1)

这不对:

y_pred_bool = np.argmax(y_pred, axis=1)

Argmax仅用于分类交叉熵损失和softmax输出。对于二进制交叉熵和S形输出,应将输出取整,这等于阈值预测> 0.5:

y_pred_bool = np.round(y_pred)

这是Keras计算二进制精度的方法。