我有一个这样的数据文件:
"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()));
});
答案 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)) }