如何在Spark

时间:2015-10-19 20:16:19

标签: java apache-spark

我有一个这样的数据文件:

"id"; "a"; "b"; "c"; "d"; "e"; "f"; "outcome"
1144216938;1988;0;0;1;1965.115431348724;19.07168894289186;0
1093965329;2004;1;1;1;302.2244897959184;16.762951334379906;1
....

第一列表示每种情况的id标签,而最后一列表示二进制结果,0或1.中间的所有变量都用于逻辑回归模型(我没有规范化它们然而)。我用Spark阅读了文件:

JavaRDD<String> data = sc.textFile(filename);
JavaRDD<LabeledPoint> parseddata = data
    .map((String line) -> {
        String[] parts = line.split(";");
        double[] points = new double[parts.length - 1];
        for (int i = 0; i < (parts.length - 1); i++) {
            points[i] = Double.valueOf(parts[i]);
        }
        return new LabeledPoint(Double.valueOf(parts[parts.length - 1]), Vectors.dense(points));
    });

我不熟悉LabeledPoint的数据结构,所以这可能很容易解决,但我不明白......所以我有三个相关的问题:

  • 如何摆脱文件头?现在我只是从文件中删除它:

修改 根据eliasah评论,这应该可以解决问题:

    // retrieve the header
    String first = data.first();
    // filter it out
    JavaRDD<String> filteredData = data.filter((String s) -> {
       return !s.contains(first);
    });

结束编辑

  • 有没有办法将第一列映射为行名,因此要将其从回归模型中使用的点中排除 - 除了使用:

    for (int i = 1; i < (parts.length - 1); i++) {
        points[i] = Double.valueOf(parts[i]);
    }
    
  • 最后,如何将预测映射到正确的&#34; id&#34;当我从回归模型中检索预测时:

    JavaRDD<Tuple2<Object, Object>> predictionAndLabels = test.map((LabeledPoint p) -> {
       Double prediction = model.predict(p.features());
       return new Tuple2<Object, Object>(prediction, p.label());
    });
    

编辑2 尽管答案都说明了,但我能想到的只有:

JavaRDD<Tuple2<Object, Object>> results = filteredData.map((String line) -> {
        String[] parts = line.split(";");
        double[] points = new double[parts.length - 1];
        //skip first column with npi values
        for (int i = 1; i < (parts.length - 1); i++) {
            points[i] = Double.valueOf(parts[i]);
        }
        LabeledPoint labeledPoint = new LabeledPoint(Double.valueOf(parts[parts.length - 1]), Vectors.dense(points));
        return new Tuple2<Object, Object>(parts[0], model.predict(labeledPoint.features()));
    });

这很遗憾,因为我基本上再次重做地图......这是正确的方法吗?

编辑3

感谢eliasah的其他评论,我现在过滤数据:

JavaRDD<Tuple2<String, LabeledPoint>> parsedData = filteredData.map((String line) -> {
 String[] parts = line.split(";");
 double[] points = new double[parts.length - 1];
 for (int i = 1; i < (parts.length - 1); i++) {
     points[i] = Double.valueOf(parts[i]);
 }
 return new Tuple2<String, LabeledPoint>(parts[0], new LabeledPoint(Double.valueOf(parts[parts.length - 1]), Vectors.dense(points)));
 });

我用它来训练:

JavaRDD<LabeledPoint> training = parsedData
     .map((Tuple2<String, LabeledPoint> z) -> {
         return z._2();
     });

使用以下方法检索每个案例的概率:

JavaRDD<Tuple2<String, Double>> results = parsedData
     .map((Tuple2<String, LabeledPoint> z) -> {
         return new Tuple2<String, Double>(z._1(), model.predict(z._2().features()));
     });

1 个答案:

答案 0 :(得分:0)

关于标题,我通常使用标题是rdd.first()来获取标题,然后是rdd上的过滤器:

String header = data.first();
JavaRDD<String> filteredData = data.filter((String s) -> {
   return !s.contains(header);
});

关于最后一个问题,Scala I映射到第二部分,然后根据if是稀疏还是密集,我创建了这样的矢量。

你需要跟踪你的id标记点RDD [(Int,LabeledPoint)](我更熟悉scala抱歉)然后你可以mapreduce over rdd来预测labelpoint.feature

rdd.map{ case (id,p) => (id,model.predict(p.features)) }