使用 TensorFlow 训练不平衡数据
Training on imbalanced data using TensorFlow
情况:
我想知道当我的训练数据在 2 个标签之间的标签分布不平衡时如何最佳地使用 TensorFlow。例如,假设 MNIST tutorial 被简化为仅区分 1 和 0,其中我们可用的所有图像都是 1 或 0。当我们有大约 50% 的每种类型的图像进行训练和测试时,使用提供的 TensorFlow 教程进行训练很简单。但是如果我们数据中 90% 的可用图像是 0 而只有 10% 是 1 的情况呢?我观察到,在这种情况下,TensorFlow 例行地将我的整个测试集预测为 0,实现了毫无意义的 90% 的准确率。
我已经成功使用的一个策略是随机选择一批 0 和 1 均匀分布的训练。这种方法确保我仍然可以使用我所有的训练数据并产生不错的结果,准确率低于 90%,但 classifier 更有用。由于在这种情况下准确性对我来说有点无用,我选择的指标通常是 ROC 曲线下的面积 (AUROC),这会产生比 .50 高得多的结果。
问题:
(1) 我描述的策略是一种可接受的或最佳的不平衡数据训练方法,还是有更好的方法?
(2) 由于准确性指标在数据不平衡的情况下没有那么有用,是否有另一个指标可以通过改变成本函数来最大化?我当然可以计算 AUROC post-training,但是我可以以最大化 AUROC 的方式进行训练吗?
(3) 是否可以对我的成本函数进行一些其他更改以改善不平衡数据的结果?目前,我正在使用 TensorFlow 教程中给出的默认建议:
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
我听说这可以通过增加错误分类较小标签的成本来实现 class,但我不确定如何做到这一点。
1) 是的。这是一种广受欢迎的应对不平衡数据的策略。但是只有当你使用 SGD 时,这种策略在神经网络中才有用。
另一种平衡训练数据的简单方法是使用加权示例。当看到不平衡的例子时,只需将 per-instance 损失放大 weight/smaller。如果你使用在线梯度下降,当看到不平衡的例子时,它可以像使用 larger/smaller 学习率一样简单。
不确定 2。
我是一个与不平衡数据作斗争的人。我的应对不平衡数据的策略如下。
1) 使用成本函数同时计算 0 和 1 标签,如下所示。
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(_pred) + (1-y)*tf.log(1-_pred), reduction_indices=1))
2) 使用 SMOTE,过采样方法使 0 和 1 标签的数量相似。参考这里,http://comments.gmane.org/gmane.comp.python.scikit-learn/5278
当我尝试制作信用评级模型时,这两种策略都奏效了。
逻辑回归是处理不平衡数据和预测违约率等二元分类的典型方法。 AUROC 是应对不平衡数据的最佳指标之一。
(1)用你的策略没问题。我也在处理不平衡数据,我尝试首先使用下采样和上采样方法使训练集均匀分布。或者使用集成方法用均匀分布的子集训练每个 classifier。
(2)我还没有看到任何最大化AUROC的方法。我的想法是 AUROC 基于真阳性和假阳性率,这并不能说明它在每个实例上的效果如何。因此,它不一定能最大化分离 classes 的能力。
(3)关于按class个实例的比例对成本进行加权,类似于Loss function for class imbalanced binary classifier in Tensor flow
和答案。
关于不平衡数据集,首先想到的两种方法是(提升正样本的权重,采样以实现平衡的批次分布)。
增加正样本的权重
这是指在正样本少得多的数据集上进行训练时,会增加错误分类正样本的损失。这会激励 ML 算法学习更适合正样本的参数。对于二进制分类,tensorflow 中有一个简单的 API 可以实现这一点。请参阅下面引用的 (weighted_cross_entropy)
批量抽样
这涉及对数据集进行采样,以便每批训练数据具有均匀分布的正样本到负样本。这可以使用 tensorflow 提供的拒绝采样 API 来完成。
情况:
我想知道当我的训练数据在 2 个标签之间的标签分布不平衡时如何最佳地使用 TensorFlow。例如,假设 MNIST tutorial 被简化为仅区分 1 和 0,其中我们可用的所有图像都是 1 或 0。当我们有大约 50% 的每种类型的图像进行训练和测试时,使用提供的 TensorFlow 教程进行训练很简单。但是如果我们数据中 90% 的可用图像是 0 而只有 10% 是 1 的情况呢?我观察到,在这种情况下,TensorFlow 例行地将我的整个测试集预测为 0,实现了毫无意义的 90% 的准确率。
我已经成功使用的一个策略是随机选择一批 0 和 1 均匀分布的训练。这种方法确保我仍然可以使用我所有的训练数据并产生不错的结果,准确率低于 90%,但 classifier 更有用。由于在这种情况下准确性对我来说有点无用,我选择的指标通常是 ROC 曲线下的面积 (AUROC),这会产生比 .50 高得多的结果。
问题:
(1) 我描述的策略是一种可接受的或最佳的不平衡数据训练方法,还是有更好的方法?
(2) 由于准确性指标在数据不平衡的情况下没有那么有用,是否有另一个指标可以通过改变成本函数来最大化?我当然可以计算 AUROC post-training,但是我可以以最大化 AUROC 的方式进行训练吗?
(3) 是否可以对我的成本函数进行一些其他更改以改善不平衡数据的结果?目前,我正在使用 TensorFlow 教程中给出的默认建议:
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
我听说这可以通过增加错误分类较小标签的成本来实现 class,但我不确定如何做到这一点。
1) 是的。这是一种广受欢迎的应对不平衡数据的策略。但是只有当你使用 SGD 时,这种策略在神经网络中才有用。
另一种平衡训练数据的简单方法是使用加权示例。当看到不平衡的例子时,只需将 per-instance 损失放大 weight/smaller。如果你使用在线梯度下降,当看到不平衡的例子时,它可以像使用 larger/smaller 学习率一样简单。
不确定 2。
我是一个与不平衡数据作斗争的人。我的应对不平衡数据的策略如下。
1) 使用成本函数同时计算 0 和 1 标签,如下所示。
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(_pred) + (1-y)*tf.log(1-_pred), reduction_indices=1))
2) 使用 SMOTE,过采样方法使 0 和 1 标签的数量相似。参考这里,http://comments.gmane.org/gmane.comp.python.scikit-learn/5278
当我尝试制作信用评级模型时,这两种策略都奏效了。
逻辑回归是处理不平衡数据和预测违约率等二元分类的典型方法。 AUROC 是应对不平衡数据的最佳指标之一。
(1)用你的策略没问题。我也在处理不平衡数据,我尝试首先使用下采样和上采样方法使训练集均匀分布。或者使用集成方法用均匀分布的子集训练每个 classifier。
(2)我还没有看到任何最大化AUROC的方法。我的想法是 AUROC 基于真阳性和假阳性率,这并不能说明它在每个实例上的效果如何。因此,它不一定能最大化分离 classes 的能力。
(3)关于按class个实例的比例对成本进行加权,类似于Loss function for class imbalanced binary classifier in Tensor flow 和答案。
关于不平衡数据集,首先想到的两种方法是(提升正样本的权重,采样以实现平衡的批次分布)。
增加正样本的权重 这是指在正样本少得多的数据集上进行训练时,会增加错误分类正样本的损失。这会激励 ML 算法学习更适合正样本的参数。对于二进制分类,tensorflow 中有一个简单的 API 可以实现这一点。请参阅下面引用的 (weighted_cross_entropy)
批量抽样 这涉及对数据集进行采样,以便每批训练数据具有均匀分布的正样本到负样本。这可以使用 tensorflow 提供的拒绝采样 API 来完成。