如何将Spark MLlib RandomForestModel.predict响应作为文本值YES / NO?

时间:2015-06-03 14:38:19

标签: java apache-spark machine-learning apache-spark-mllib

您好我正在尝试使用Apache Spark MLLib实现RandomForest算法。我有csv格式的数据集,具有以下功能

DayOfWeek(int),AlertType(String),Application(String),Router(String),Symptom(String),Action(String)
0,Network1,App1,Router1,Not reachable,YES
0,Network1,App2,Router5,Not reachable,NO

我想使用RandomForest MLlib并对最后一个字段Action进行预测,我希望响应为YES / NO。

我正在关注github的代码以创建RandomForest模型。由于我有除了一个int功能之外的所有分类功能,我使用以下代码将它们转换为JavaRDD<LabeledPoint>,请让我知道它的错误

// Load and parse the data file.
        JavaRDD<String> data = jsc.textFile("/tmp/xyz/data/training-dataset.csv");

       // I have 14 features so giving 14 as arg to the following
        final HashingTF tf = new HashingTF(14);

        // Create LabeledPoint datasets for Actionable and nonactionable
        JavaRDD<LabeledPoint> labledData = data.map(new Function<String, LabeledPoint>() {
            @Override public LabeledPoint call(String alert) {
                List<String> featureList = Arrays.asList(alert.trim().split(","));
                String actionType = featureList.get(featureList.size() - 1).toLowerCase();
                return new LabeledPoint(actionType.equals("YES")? 1 : 0, tf.transform(featureList));
            }
        });

同样在上面我创建了testdata并使用以下代码进行预测

JavaPairRDD<Double, Double> predictionAndLabel =
        testData.mapToPair(new PairFunction<LabeledPoint, Double, Double>() {
          @Override
          public Tuple2<Double, Double> call(LabeledPoint p) {
            return new Tuple2<Double, Double>(model.predict(p.features()), p.label());
          }
        });

如何根据我的最后一个字段获得预测操作和预测应该是YES / NO?当前预测方法返回双倍无法理解我如何实现它?我也是在LabledPoint中遵循正确的分类功能方法,请指导我是机器学习和Spark MLlib的新手。

2 个答案:

答案 0 :(得分:1)

我对scala版本比较熟悉,但我会尽力帮忙。

您需要将目标变量(Action)和所有分类功能映射到从0开始的级别,如0,1,2,3 ...例如router1,router2,... router5进入0,1,2。 ..4。与您的目标变量相同,我认为这是您实际映射的唯一一个,是/否为1/0(我不确定您的tf.transform(featureList)实际上在做什么)。

完成此操作后,您可以训练您的Randomforest分类器,指定分类要素的地图。基本上它需要你告诉哪些功能是分类的以及它们有多少级别,这是scala版本,但你可以很容易地将其翻译成java:

val categoricalFeaturesInfo = Map[Int, Int]((2,2),(3,5))

这基本上是说在你的特征列表中,第三个(2)有2个等级(2,2),第四个(3)有5个等级(3,5)。其余的被认为是双打。

现在,您在将分类器与其他参数一起训练时传递categoricalFeaturesInfo:

val modelRF = RandomForest.trainClassifier(trainingData, numClasses, categoricalFeaturesInfo,numTrees, featureSubsetStrategy, impurity, maxDepth, maxBins)

现在,当您需要对其进行评估时,预测函数将返回一个双0,1并且您可以使用它来计算所需的准确度,精度或任何度量。

这是一个示例(再次抱歉scala)如果你有一个testData,你做了与以前相同的转换:

val predictionAndLabels = testData.map { point =>
  val prediction = modelRF.predict(point.features)
  (point.label, prediction)
} 

此处您的结果清晰,标签为1/0,预测值也为1/0,精度,精度和召回的任何计算都很简单。

我希望它有所帮助!!

答案 1 :(得分:0)

你正朝着正确的方向前进,而你已经设法训练了一个很棒的模型。

对于二进制分类,它将返回0.0或1.0,并由您决定将其映射回字符串值。