Keras MLP分类器无法学习

时间:2019-06-10 09:34:09

标签: python machine-learning keras classification data-science

我有这样的数据 enter image description here

enter image description here

共有29列,我必须预测其中的 winPlacePerc (数据帧的最末端)在 1 之间(高性能)到 0 (低性能)

29 列中的 25 数字数据3是ID(对象)1是绝对的

我删除了所有 Id列(因为它们都是唯一的),并且还将分类(matchType)数据编码为一种热编码 >

完成所有这些操作后,我剩下41列(热一遍)

after one hot encoded

这就是我创建数据的方式

X = df.drop(columns=['winPlacePerc'])
#creating a dataframe with only the target column
y = df[['winPlacePerc']]

现在我的X有40列,这是我的标签数据,看起来像

> y.head()

winPlacePerc
0   0.4444
1   0.6400
2   0.7755
3   0.1667
4   0.1875

我也碰巧拥有大量数据,例如40万个数据,因此出于测试目的,我正在训练其中的一部分,使用sckit进行

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.997, random_state=32)

可提供将近13,000的训练数据

对于模型,我使用的是 Keras顺序模型

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dense, Dropout, Activation
from keras.layers.normalization import BatchNormalization
from keras import optimizers

n_cols = X_train.shape[1]

model = Sequential()

model.add(Dense(40, activation='relu', input_shape=(n_cols,)))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='mean_squared_error',
              optimizer='Adam',
              metrics=['accuracy'])

model.fit(X_train, y_train,
          epochs=50,
          validation_split=0.2,
          batch_size=20)

由于我的y标签数据介于0和1之间,因此我将 Sigmoid 层用作我的输出层

这是训练与验证损失与准确性图

enter image description here enter image description here

我还尝试使用 step 函数和二进制交叉熵损失函数

将标签转换为 binary

之后,y标签数据看起来像

> y.head()

winPlacePerc
0   0
1   1
2   1
3   0
4   0

和更改损失函数

model.compile(loss='binary_crossentropy',
              optimizer='Adam',
              metrics=['accuracy'])

enter image description here

这种方法比以前更糟糕

如您所见,它在某个时期后没有学习,即使我正在获取所有数据而不是其中的一部分,也会发生这种情况

在此操作无效后,我还使用了辍学并尝试了添加更多层,但是这里没有任何作用

现在我的问题是,我在做什么错了?这是错误的层还是数据中的问题,我该如何加以改进?

2 个答案:

答案 0 :(得分:1)

要弄清一切-这是一个回归问题,因此使用准确性实际上没有意义,因为您永远无法预测0.23124的确切值。

首先,您肯定要在将值传递到网络之前规范化您的值(而不是热编码的值)。尝试以StandardScaler作为开始。

第二,我建议您在输出层中更改激活功能-尝试使用linear,因为损耗mean_squared_error应该没问题。

为了验证您对模型“准确性” 进行建模,将预测值与实际值一起绘制-这应该使您有机会直观地验证结果。但是,话虽如此,您的损失看起来已经相当不错了。

检查this post,应该使您对什么(激活和丢失功能)以及何时使用有了很好的了解。

答案 1 :(得分:1)

from sklearn.preprocessing import StandardScaler

n_cols = X_train.shape[1]
ss = StandardScaler()
X_train = ss.fit_transform(X_train)

model = Sequential()    
model.add(Dense(128, activation='relu', input_shape=(n_cols,)))
model.add(Dense(64, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(1))

model.compile(loss='mean_squared_error',
              optimizer='Adam',
              metrics=['mean_squared_error'])

model.fit(X_train, y_train,
          epochs=50,
          validation_split=0.2,
          batch_size=20)
  • 标准化数据
  • 为您的网络增加深度
  • 使最后一层线性化

准确性不是衡量回归的好指标。让我们看一个示例

predictions: [0.9999999, 2.0000001, 3.000001]
ground Truth: [1, 2, 3]

Accuracy = No:of Correct / Total => 0 /3 = 0

精度为0,但预测非常接近基本事实。另一方面,MSE将非常低,表明预测与基本事实的偏差非常小。