Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Spark MLlib中不平衡数据集的处理_Apache Spark_Machine Learning_Classification_Apache Spark Mllib - Fatal编程技术网

Apache spark Spark MLlib中不平衡数据集的处理

Apache spark Spark MLlib中不平衡数据集的处理,apache-spark,machine-learning,classification,apache-spark-mllib,Apache Spark,Machine Learning,Classification,Apache Spark Mllib,我正在研究一个具有高度不平衡数据集的特定二进制分类问题,我想知道是否有人尝试使用Spark的MLlib实现处理分类问题中不平衡数据集(例如)的特定技术 我正在使用MLLib的随机林实现,并且已经尝试了对较大的类进行随机欠采样的最简单方法,但效果不如我预期的好 如果您对类似问题有任何反馈,我将不胜感激 谢谢,带Spark ML的班级重量 此时此刻,随机林算法的类权重仍在开发中(请参阅) 但是如果您愿意尝试其他分类器,请使用此功能 假设数据集中有80%的正数(label==1),因此理论上我们希望对

我正在研究一个具有高度不平衡数据集的特定二进制分类问题,我想知道是否有人尝试使用Spark的MLlib实现处理分类问题中不平衡数据集(例如)的特定技术

我正在使用MLLib的随机林实现,并且已经尝试了对较大的类进行随机欠采样的最简单方法,但效果不如我预期的好

如果您对类似问题有任何反馈,我将不胜感激

谢谢,

带Spark ML的班级重量 此时此刻,随机林算法的类权重仍在开发中(请参阅)

但是如果您愿意尝试其他分类器,请使用此功能

假设数据集中有80%的正数(label==1),因此理论上我们希望对正数类进行“下采样”。 logistic损失目标函数应处理权重较高的阴性类别(标签==0)

下面是Scala中生成此权重的示例,我们为数据集中的每条记录向数据帧添加一个新列:

def balanceDataset(dataset: DataFrame): DataFrame = {

    // Re-balancing (weighting) of records to be used in the logistic loss objective function
    val numNegatives = dataset.filter(dataset("label") === 0).count
    val datasetSize = dataset.count
    val balancingRatio = (datasetSize - numNegatives).toDouble / datasetSize

    val calculateWeights = udf { d: Double =>
      if (d == 0.0) {
        1 * balancingRatio
      }
      else {
        (1 * (1.0 - balancingRatio))
      }
    }

    val weightedDataset = dataset.withColumn("classWeightCol", calculateWeights(dataset("label")))
    weightedDataset
  }
然后,我们创建一个classier,如下所示:

new LogisticRegression().setWeightCol("classWeightCol").setLabelCol("label").setFeaturesCol("features")
有关更多详细信息,请参见此处:

-预测能力 您应该检查另一个问题-您的功能是否对您试图预测的标签具有“预测能力”。在欠采样后,精度仍然较低的情况下,这可能与数据集本质上是不平衡的事实无关


我会做一个探索性的数据分析——如果分类器没有比随机选择做得更好,那么就有可能在特性和类之间根本没有联系

  • 对标签上的每个特征执行相关性分析
  • 为特征生成特定于类别的直方图(即,为给定类别绘制每个类别的数据直方图 同一轴上的特征)也是显示 这两个类之间的特征差别很大

过度拟合-训练集上的低错误和测试集上的高错误可能表明您使用了过度灵活的功能集进行了过度拟合


偏差方差-检查分类器是否存在高偏差或高方差问题

  • 培训错误与验证错误-将验证错误和培训集错误绘制为培训示例的函数(进行增量学习)
    • 如果这些线似乎收敛到相同的值,并且在末尾很接近,那么您的分类器具有较高的偏差。在这种情况下,添加更多的数据不会有帮助。 将分类器更改为具有更高方差的分类器,或者简单地降低当前分类器的正则化参数
    • 另一方面,如果行之间相距很远,并且训练集错误较低,但验证错误较高,则分类器的方差太大。在这种情况下,获取更多数据很可能会有所帮助。如果获得更多数据后,方差仍然过高,则可以增加正则化参数

我使用@Serendipity的解决方案,但我们可以优化balanceDataset函数以避免使用udf。我还添加了更改正在使用的标签列的功能。这是我最终使用的函数的版本:

def balanceDataset(dataset: DataFrame, label: String = "label"): DataFrame = {
  // Re-balancing (weighting) of records to be used in the logistic loss objective function
  val (datasetSize, positives) = dataset.select(count("*"), sum(dataset(label))).as[(Long, Double)].collect.head
  val balancingRatio = positives / datasetSize

  val weightedDataset = {
    dataset.withColumn("classWeightCol", when(dataset(label) === 0.0, balancingRatio).otherwise(1.0 - balancingRatio))
  }
  weightedDataset
}
我们创建分类器,如他所述:

new LogisticRegression().setWeightCol("classWeightCol").setLabelCol("label").setFeaturesCol("features")

@dbakr您对不平衡数据集的偏差预测得到了答案吗

虽然我不确定这是否是您最初的计划,但请注意,如果您首先通过比率r对数据集的大多数类进行二次采样,那么,为了获得Spark逻辑回归的无伪预测,您可以: -使用
transform()
函数提供的rawPrediction,并使用
log(r)

-或者,您可以使用
.setWeightCol(“classWeightCol”)
对回归进行权重训练(请参阅引用的文章,以确定权重中必须设置的值)。

SMOTEBoost算法建议使用弱学习算法训练数据集。为什么不实现这样的功能:@eliasah,我的意思是,与负面示例相比,我的数据集包含的正面示例非常少(大约每100个包含1个)。经过训练的分类器偏向于多数(否定)类,其预测精度高于该类,但预测精度低于少数类。“未按预期工作”意味着在进行10倍交叉验证测试时,分类器的精度约为60-70%(即60-70%的阳性病例被正确分类)。您的阳性分类有多紧密?特征是离散的还是连续的?RF适用于具有本地连接的离散数据集上的离散数据。如果点是全局连通的(一个大的丛),那么你可以考虑支持向量机、谱聚类,甚至k-均值。你对这项索赔有任何参考资料吗?我并不是说这不是真的,但至少对我来说,这不是直观的。“二进制分类不受不平衡数据的影响”-这绝对不是真的。谢谢@Serendipity的提示。我不知道Spark ML中的逻辑回归支持类权重。@dbakr您需要一个实现示例吗?我刚试过。谢谢@Serendipity!我注意到的一点是,当分类器在加权数据集上训练时,输出概率(我需要实际概率,而不是预测的标签)没有得到很好的校准。这意味着生成的概率与原始数据集分布不匹配,而是根据加权数据集进行调整。这反过来会导致验证集上的日志损失测量值高于手动欠采样时的日志损失测量值