Java 将自定义字段添加到Spark ML LabeldPoint

Java 将自定义字段添加到Spark ML LabeldPoint,java,machine-learning,apache-spark,Java,Machine Learning,Apache Spark,如何向预测结果中添加一些自定义字段(即用户id) List<org.apache.spark.mllib.regression.LabeledPoint> localTesting = ... ;// // I want to add some identifier to each LabeledPoint DataFrame localTestDF = jsql.createDataFrame(jsc.parallelize(stu

如何向预测结果中添加一些自定义字段(即用户id)

        List<org.apache.spark.mllib.regression.LabeledPoint> localTesting = ... ;//
        // I want to add some identifier to each LabeledPoint

        DataFrame localTestDF = jsql.createDataFrame(jsc.parallelize(studyData.localTesting), LabeledPoint.class);
        DataFrame predictions = model.transform(localTestDF);
        Row[] collect = predictions.select("label", "probability", "prediction").collect();
        for (Row r : collect) {
            // and want to return identifier here.
            // so do I save I to database.
            int userNo = Integer.parseInt(r.get(0).toString());
            double prob = Double.parseDouble(r.get(1).toString());
            int prediction = Integer.parseInt(r.get(2).toString());
            log.debug(userNo + "," + prob + ", " + prediction);
        }
我的意思是,我不仅要得到预测数据(特征、标签、概率…),还要得到一些我想要的自定义字段。例如userNo、user\u id等等 从结果中:预测。选择(“……”)

更新

解决了。一条线应该是固定的


由于不使用低级MLlib API,因此根本不需要使用
LabeledPoint
。创建一个
DataFrame
之后,您得到的只是一个具有特定值的
行,重要的*是与管道中的参数匹配的类型和列名

在Scala中,您可以使用任何case类

org.apache.spark.mllib.linalg.Vector;案例类
案例类LabeledPointWithMeta(用户编号:String,标签:Double,特征:Vector)
val rdd:rdd[LabeledPointWithMeta]=???
val df=rdd.toDF
为了能够从中使用它,您可能应该添加
@BeanInfo
注释:

import scala.beans.BeanInfo

@BeanInfo
case class LabeledPointWithMeta(...)
在普通Java中,您可以根据以下命令执行**:

import org.apache.spark.mllib.linalg.Vector;

public static class LabeledPointWithMeta implements Serializable {
  private int userNo;
  private double label;
  private Vector vector;

  public int getUserNo() {
    return userNo;
  }

  public void setUserNo(int userNo) {
    this.userNo = userNo;
  }

  public double getLabel() {
    return label;
  }

  public void setLabel(double label) {
    this.label = label;
  }

  public Vector getVector() {
    return vector;
  }

  public void seVector(Vector vector) {
    this.vector = vector;
  }

}
在那之后:

JavaRDD<LabeledPointWithMeta> myPoints = ...;

DataFrame df = sqlContext.createDataFrame(myPoints LabeledPointWithMeta.class);
如果您想使用MLlib,它不会对您有所帮助,但是这一部分可以通过简单的
RDD
转换(如
zip
)轻松处理


*将一些元数据添加到,但您无法从
标签点获得该元数据


**我还没有测试过上面的代码,所以它可能会包含一些错误。

我还没有找到可靠的方法来实现这一点。到目前为止,我已经将验证子集的相关元数据存储在
标签
对象中,方法是将其修改为浮点数(在我的示例中,它看起来像
datetime.primary_key
,例如2015年1月1日的
150101.12345
,主键12345)。据我所知,没有内置系统来存储有关
LabeledPoint
对象的元数据。我们可以尝试RDD中的.zip函数,并将其与userId、actualLabel和predictedLabel进行映射吗。此外,Java示例使用普通映射来连接预测。zip函数假定两个RDD具有相同数量的分区和每个分区中相同数量的元素(例如,一个是通过另一个上的映射生成的)。@AnchitChoudhry不可能使用spark.ml?(RDD使用高级功能,因此不直接处理RDD。)太棒了!真的很有帮助。我将根据这些代码进行尝试!:)
            DataFrame localTestDF = jsql.createDataFrame(jsc.parallelize(studyData.localTesting), NoLabeledPoint.class);
import scala.beans.BeanInfo

@BeanInfo
case class LabeledPointWithMeta(...)
import org.apache.spark.mllib.linalg.Vector;

public static class LabeledPointWithMeta implements Serializable {
  private int userNo;
  private double label;
  private Vector vector;

  public int getUserNo() {
    return userNo;
  }

  public void setUserNo(int userNo) {
    this.userNo = userNo;
  }

  public double getLabel() {
    return label;
  }

  public void setLabel(double label) {
    this.label = label;
  }

  public Vector getVector() {
    return vector;
  }

  public void seVector(Vector vector) {
    this.vector = vector;
  }

}
JavaRDD<LabeledPointWithMeta> myPoints = ...;

DataFrame df = sqlContext.createDataFrame(myPoints LabeledPointWithMeta.class);
DataFrame localTestDF = jsql.createDataFrame(
    jsc.parallelize(studyData.localTesting),
    NoLabeledPoint.class
);