数据总共有29列,我需要预测其中winPlacePerc(数据框的末端),其值介于1(高百分比)到0(低百分比)之间
在29列中,25列是数值数据,3列是ID(对象类型),1列是分类数据
我删除了所有的ID列(因为它们都是唯一的),并将分类数据(matchType)编码为独热编码
完成这些操作后,我剩下41列(经过独热编码后)
这是我创建数据的方式
X = df.drop(columns=['winPlacePerc'])#创建仅包含目标列的数据框y = df[['winPlacePerc']]
现在我的X有40列,我的标签数据看起来像这样
> y.head()winPlacePerc0 0.44441 0.64002 0.77553 0.16674 0.1875
我还拥有大量数据,大约40万条数据,为了测试目的,我只训练其中一小部分,使用sckit来实现
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.997, random_state=32)
这样可以得到大约1.3万条数据用于训练
对于模型,我使用的是Keras顺序模型
from keras.models import Sequentialfrom keras.layers import Densefrom keras.layers import Dense, Dropout, Activationfrom keras.layers.normalization import BatchNormalizationfrom keras import optimizersn_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层作为我的输出层
这是训练和验证的损失与准确率图
我还尝试将标签转换为二进制,使用阶跃函数和二元交叉熵损失函数
转换后的y标签数据看起来像这样
> y.head()winPlacePerc0 01 12 13 04 0
并更改损失函数
model.compile(loss='binary_crossentropy', optimizer='Adam', metrics=['accuracy'])
这种方法比之前的更糟
如你所见,它在某些轮次后就不再学习了,即使我使用所有数据而不是其中的一小部分,情况也是如此
在这些方法都不奏效后,我还使用了 dropout并尝试增加更多层,但这些方法在这里都不起作用
现在我的问题是,我在这里做错了什么?是层的问题还是数据的问题?我怎样才能改进这一点?
回答:
为了澄清,这是一个回归问题,因此使用准确率并不真的有意义,因为你永远无法精确预测到0.23124这样的值。
首先,你肯定需要在将数据传入网络之前对其进行标准化(不包括独热编码的数据)。可以先尝试使用StandardScaler
。
其次,我建议更改输出层的激活函数 – 尝试使用linear
,并将损失函数设置为mean_squared_error
应该没问题。
为了验证你的模型的“准确率”,可以将预测值和实际值一起绘制出来 – 这应该能让你有机会视觉上验证结果。然而,话虽如此,你的损失看起来已经相当不错了。
查看这篇文章,应该能让你很好地理解何时以及如何使用(激活函数和损失函数)。