如何正确处理稀疏特征,避免分类神经网络表现不佳?
How to handle correctly sparse features to avoid poor performance of classification neural network?
我正在尝试了解稀疏神经网络的工作原理。我有两个 classes 的大约 40k 行的非常稀疏的数据。数据集如下所示:
RA0 RA1 RA2 RA3 RA4 RA5 RA6 RA7 RA8 RA9 RB0 RB1 RB2 RB3 RB4 RB5 RB6 RB7 RB8 RB9
50 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
51 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
52 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
53 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
54 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
55 1.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
56 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
57 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
58 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
59 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
60 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
61 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
62 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
63 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
如您所见,有些行只有 0。名称为 RA
的列是 class 0
的特征,名称为 RB
的列是 class 1
的特征,因此与实际 labels
相同的数据集] 看起来像这样:
RA0 RA1 RA2 RA3 RA4 RA5 RA6 RA7 RA8 RA9 ... RB1 RB2 RB3 RB4 RB5 RB6 RB7 RB8 RB9 label
50 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
51 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
52 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
53 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
54 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
55 1.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
56 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
57 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
58 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
59 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
60 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
我使用 Keras
做了一个简单的神经网络模型,但该模型没有学习,而且在训练数据集上的准确率很少超过 52%。我尝试了同一型号的两种变体:
变体 1:
def build_nn(n_features,lr = 0.001):
_input = Input(shape = (n_features,),name = 'input',sparse = True)
x = Dense(12,kernel_initializer = 'he_uniform',activation = 'relu')(_input)
x = Dropout(0.5)(x)
x = Dense(8,kernel_initializer = 'he_uniform',activation = 'relu')(x)
x = Dropout(0.5)(x)
x = Dense(2,kernel_initializer = 'he_uniform',activation = 'softmax')(x)
nn = Model(inputs = [_input],outputs = [x])
nn.compile(loss='sparse_categorical_crossentropy',optimizer=Adam(lr = lr),metrics=['accuracy'])
return nn
变体 2:
def build_nn(feature_layer,lr = 0.001):
feature_inputs = {}
for feature in feature_layer:
feature_inputs[feature.key] = Input(shape = (1,),name = feature.key)
feature_layer = tf.keras.layers.DenseFeatures(feature_layer)
feature_inputs_n = feature_layer(feature_inputs)
x = Dense(12,kernel_initializer = 'he_uniform',activation = 'relu')(feature_inputs_n)
x = Dropout(0.5)(x)
x = Dense(8,kernel_initializer = 'he_uniform',activation = 'relu')(x)
x = Dropout(0.5)(x)
x = Dense(2,kernel_initializer = 'he_uniform',activation = 'softmax')(x)
nn = Model(inputs = [v for v in feature_inputs.values()],outputs = [x])
nn.compile(loss='sparse_categorical_crossentropy',optimizer=Adam(lr = lr),metrics=['accuracy'])
return nn
做变体 2 的动机是因为特征稀疏,我认为这可能会对模型的性能产生影响,所以我遵循了 this tensorflow guide。
此外,使用 keras api:
提供的 to_categorical
函数将标签转换为分类标签
y_train2 = to_categorical(y_train)
y_test2 = to_categorical(y_test)
我的问题是:
我的模型是否错误(尤其是变体 2)或者我对稀疏特征的表示有误以及应该如何处理这些特征?
RA
和 RB
是两个不同的 class 的特征,因为有行全是 0,我是否应该添加第三个 class 表示未知 class 或删除仅包含 0 的行?
因为 RA
和 RB
映射两个不同的 classes,我应该做两个单独的模型,一个用于列 RA
和 class 0 和另一个用于列 RB
和 class 1?
我还发布了 train/test 模型准确度的图像:
如果需要,我也可以提供代码的任何其他部分。
编辑:
我没有放这部分是因为我觉得它与我的要求没有关系,但我似乎错了。
每个特征都是 sklearn 决策树的一个单独分支。 decision tree
寻找的 class 是交易环境中下一根蜡烛的上涨或下跌(蜡烛是具有开盘价、最低价、最高价和收盘价的工具的及时价格聚合价格)。然后,想法是抓住那些在价格时间序列中被估值的分支,并评估是否满足条件,因此如果分支处于活动状态,则值为 1。
例如,索引 55 处的分支 RA0
处于活动状态,因此值为 1
。标签计算为 np.sign(close - open)
。因此,我们的想法是,通过使用多个分支,可以改进标签的 class 化,方法是使用一个神经网络,该网络可以查看哪个分支处于活动状态以及哪个分支具有更大的权重,以便做出 class化.
这里使用sparse_categorical_crossentropy
是错误的; sparse_categorical_crossentropy
中的稀疏性指的是 标签表示 ,而不是特征。由于您使用的是单热编码标签:
y_train2 = to_categorical(y_train)
y_test2 = to_categorical(y_test)
和带有 activation = 'softmax'
的 2 个节点的最后一层(我认为这意味着你只有 2 类),你应该切换到 loss='categorical_crossentropy'
而不管稀疏性如何在你的特征.
其他一般说明:
移除 dropout,默认情况下应该 never 使用。 Dropout 用于帮助防止过度拟合 if 如果检测到这样的事情;不加批判地使用(甚至更糟,具有如此高的价值),众所周知完全阻止训练(即与您在此处报告的内容非常相似)。
从所有图层中删除 kernel_initializer = 'he_uniform'
,从而留下 default glorot_uniform
一个(有用的提示:默认值是有原因的,除非你有特定的理由并且你确切地知道你在做什么,否则不建议和他们一起玩。
我正在尝试了解稀疏神经网络的工作原理。我有两个 classes 的大约 40k 行的非常稀疏的数据。数据集如下所示:
RA0 RA1 RA2 RA3 RA4 RA5 RA6 RA7 RA8 RA9 RB0 RB1 RB2 RB3 RB4 RB5 RB6 RB7 RB8 RB9
50 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
51 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
52 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
53 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
54 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
55 1.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
56 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
57 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
58 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
59 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
60 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
61 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
62 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
63 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
如您所见,有些行只有 0。名称为 RA
的列是 class 0
的特征,名称为 RB
的列是 class 1
的特征,因此与实际 labels
相同的数据集] 看起来像这样:
RA0 RA1 RA2 RA3 RA4 RA5 RA6 RA7 RA8 RA9 ... RB1 RB2 RB3 RB4 RB5 RB6 RB7 RB8 RB9 label
50 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
51 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
52 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
53 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
54 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
55 1.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
56 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
57 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
58 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
59 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
60 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
我使用 Keras
做了一个简单的神经网络模型,但该模型没有学习,而且在训练数据集上的准确率很少超过 52%。我尝试了同一型号的两种变体:
变体 1:
def build_nn(n_features,lr = 0.001):
_input = Input(shape = (n_features,),name = 'input',sparse = True)
x = Dense(12,kernel_initializer = 'he_uniform',activation = 'relu')(_input)
x = Dropout(0.5)(x)
x = Dense(8,kernel_initializer = 'he_uniform',activation = 'relu')(x)
x = Dropout(0.5)(x)
x = Dense(2,kernel_initializer = 'he_uniform',activation = 'softmax')(x)
nn = Model(inputs = [_input],outputs = [x])
nn.compile(loss='sparse_categorical_crossentropy',optimizer=Adam(lr = lr),metrics=['accuracy'])
return nn
变体 2:
def build_nn(feature_layer,lr = 0.001):
feature_inputs = {}
for feature in feature_layer:
feature_inputs[feature.key] = Input(shape = (1,),name = feature.key)
feature_layer = tf.keras.layers.DenseFeatures(feature_layer)
feature_inputs_n = feature_layer(feature_inputs)
x = Dense(12,kernel_initializer = 'he_uniform',activation = 'relu')(feature_inputs_n)
x = Dropout(0.5)(x)
x = Dense(8,kernel_initializer = 'he_uniform',activation = 'relu')(x)
x = Dropout(0.5)(x)
x = Dense(2,kernel_initializer = 'he_uniform',activation = 'softmax')(x)
nn = Model(inputs = [v for v in feature_inputs.values()],outputs = [x])
nn.compile(loss='sparse_categorical_crossentropy',optimizer=Adam(lr = lr),metrics=['accuracy'])
return nn
做变体 2 的动机是因为特征稀疏,我认为这可能会对模型的性能产生影响,所以我遵循了 this tensorflow guide。
此外,使用 keras api:
提供的to_categorical
函数将标签转换为分类标签
y_train2 = to_categorical(y_train)
y_test2 = to_categorical(y_test)
我的问题是:
我的模型是否错误(尤其是变体 2)或者我对稀疏特征的表示有误以及应该如何处理这些特征?
RA
和RB
是两个不同的 class 的特征,因为有行全是 0,我是否应该添加第三个 class 表示未知 class 或删除仅包含 0 的行?因为
RA
和RB
映射两个不同的 classes,我应该做两个单独的模型,一个用于列RA
和 class 0 和另一个用于列RB
和 class 1?
我还发布了 train/test 模型准确度的图像:
如果需要,我也可以提供代码的任何其他部分。
编辑: 我没有放这部分是因为我觉得它与我的要求没有关系,但我似乎错了。
每个特征都是 sklearn 决策树的一个单独分支。 decision tree
寻找的 class 是交易环境中下一根蜡烛的上涨或下跌(蜡烛是具有开盘价、最低价、最高价和收盘价的工具的及时价格聚合价格)。然后,想法是抓住那些在价格时间序列中被估值的分支,并评估是否满足条件,因此如果分支处于活动状态,则值为 1。
例如,索引 55 处的分支 RA0
处于活动状态,因此值为 1
。标签计算为 np.sign(close - open)
。因此,我们的想法是,通过使用多个分支,可以改进标签的 class 化,方法是使用一个神经网络,该网络可以查看哪个分支处于活动状态以及哪个分支具有更大的权重,以便做出 class化.
这里使用sparse_categorical_crossentropy
是错误的; sparse_categorical_crossentropy
中的稀疏性指的是 标签表示 ,而不是特征。由于您使用的是单热编码标签:
y_train2 = to_categorical(y_train)
y_test2 = to_categorical(y_test)
和带有 activation = 'softmax'
的 2 个节点的最后一层(我认为这意味着你只有 2 类),你应该切换到 loss='categorical_crossentropy'
而不管稀疏性如何在你的特征.
其他一般说明:
移除 dropout,默认情况下应该 never 使用。 Dropout 用于帮助防止过度拟合 if 如果检测到这样的事情;不加批判地使用(甚至更糟,具有如此高的价值),众所周知完全阻止训练(即与您在此处报告的内容非常相似)。
从所有图层中删除
kernel_initializer = 'he_uniform'
,从而留下 defaultglorot_uniform
一个(有用的提示:默认值是有原因的,除非你有特定的理由并且你确切地知道你在做什么,否则不建议和他们一起玩。