【问题标题】:Java : KMeans Spark Join Cluster Center into Prediction DataframeJava:KMeans Spark 将集群中心加入预测数据框
【发布时间】:2021-08-16 15:04:09
【问题描述】:

我知道 KMeansModel transform 将输出作为数据集给我们,并且输出数据帧的预测列说明了哪一列是 _c0_c1featuresprediction

但是,我也想知道这个数据框中每个特征的每个聚类中心。

我如何使用 java 来做到这一点?我希望我的代码是纯 java 的(不在 scala 中,甚至基于 scala 的 spark)。

+-----------+----------+
|   features|prediction|
+-----------+----------+
| [4.0,53.0]|         2|
| [5.0,63.0]|         3|
|[10.0,59.0]|         2|
|[13.0,49.0]|         0|
|[12.0,88.0]|         1|
|[12.0,88.0]|         1|
|[18.0,61.0]|         2|
+-----------+----------+

预期结果:

+-----------+----------+----------------+
|   features|prediction|clusterCenter   |
+-----------+----------+-------------+--+
| [4.0,53.0]|         1| [20.15,64.95]  |
| [5.0,63.0]|         0| [43.91,146.04  |
|[10.0,59.0]|         2| [20.4,68]      |
|[13.0,49.0]|         0| [43.91,146.04] |
|[12.0,88.0]|         1| [20.15,64.95]  |
|[12.0,88.0]|         2| [20.4,68]      |
|[18.0,61.0]|         3| [98.176,114.88]|
+-----------+----------+----------------+

这里是一些测试代码sn-p

List<Row> dataset = Arrays.asList(
     RowFactory.create(Vectors.dense(4,53)),
     RowFactory.create(Vectors.dense(5,63)),
     RowFactory.create(Vectors.dense(10,59)),
     RowFactory.create(Vectors.dense(13,49)),
     RowFactory.create(Vectors.dense( 12,88)),
     RowFactory.create(Vectors.dense(12,88)),
     RowFactory.create(Vectors.dense(18,61))
);

StructType schema = new StructType(new StructField[]{
     new StructField("features", new VectorUDT(), false, Metadata.empty()),
});

Dataset<Row> df = sc.createDataFrame(dataset, schema);
KMeans kMeans = new KMeans().setK(4).setMaxIter(10);
KMeansModel model = kMeans.fit(df);
Dataset<Row> predict = model.transform(df);
predict.show();

StructType centroidSchema = new StructType(new StructField[]{
    new StructField("x", DataTypes.StringType, false, Metadata.empty()),
    new StructField("y", DataTypes.StringType, false, Metadata.empty())
});

Dataset<Row> centroid = sc.createDataFrame(jsc.parallelize(model.clusterCenters()).map(s -> {
     String[] row = s.toString().replace("[","").replace("]","").split(",");
     return RowFactory.create((Object[]) row);
}), centroidSchema);
centroid = centroid .withColumn("x", centroid .col("x").cast("Double"));
centroid = centroid .withColumn("y", centroid .col("y").cast("Double"));
centroid.show();

【问题讨论】:

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


    【解决方案1】:

    我已经用以下方法解决了这个问题:

    ...
    Vector[] centroidVector = model.clusterCenters();
    Dataset<Row> prediction = model.transform(dataset);
    
    List<Tuple2<String, Integer>> centroid = new ArrayList<>();
    for (int i=0; i<centroidVector.length; i++){
        centroid.add(new Tuple2<>(Arrays.toString(centroidVector[i].toArray()), i));
    }
    
    JavaPairRDD<String, Integer> sorting = jsc.parallelize(centroid).mapToPair((Tuple2<String, Integer> s) -> new Tuple2<>(s._1, s._2)).cache();
    Dataset<Row> df = sc.createDataset(sorting.collect(), Encoders.tuple(Encoders.STRING(), Encoders.INT())).toDF("centroid","prediction").cache();
    
    Dataset<Row> result = prediction.join(df, df.col("prediction").equalTo(prediction.col("prediction"))).drop(prediction.col("prediction"));
    result=result.withColumn("features", result.col("features").cast("String"));
    result=result.withColumn("centroid", result.col("centroid").cast("String"));
    result.show();
    

    ruspini 数据集的结果:

    +-----+-----+-------------+--------------------+----------+
    |   f1|   f2|     features|            centroid|prediction|
    +-----+-----+-------------+--------------------+----------+
    |  4.0| 53.0|   [4.0,53.0]|[20.1500000000000...|         0|
    |  5.0| 63.0|   [5.0,63.0]|[20.1500000000000...|         0|
    | 10.0| 59.0|  [10.0,59.0]|[20.1500000000000...|         0|
    | 32.0| 61.0|  [32.0,61.0]|[20.1500000000000...|         0|
    | 28.0|147.0| [28.0,147.0]|[43.9130434782608...|         1|
    | 32.0|149.0| [32.0,149.0]|[43.9130434782608...|         1|
    | 41.0|150.0| [41.0,150.0]|[43.9130434782608...|         1|
    | 52.0|152.0| [52.0,152.0]|[43.9130434782608...|         1|
    | 86.0|132.0| [86.0,132.0]|[98.1764705882352...|         3|
    | 85.0|115.0| [85.0,115.0]|[98.1764705882352...|         3|
    | 85.0| 96.0|  [85.0,96.0]|[98.1764705882352...|         3|
    | 78.0| 94.0|  [78.0,94.0]|[98.1764705882352...|         3|
    | 70.0|  4.0|   [70.0,4.0]|[68.9333333333333...|         2|
    | 77.0| 12.0|  [77.0,12.0]|[68.9333333333333...|         2|
    | 83.0| 21.0|  [83.0,21.0]|[68.9333333333333...|         2|
    | 61.0| 15.0|  [61.0,15.0]|[68.9333333333333...|         2|
    +-----+-----+-------------+--------------------+----------+
    
    

    如果有人有其他方法,我想听听。

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 2017-01-01
      • 2022-01-05
      • 2019-08-25
      • 2014-08-02
      • 1970-01-01
      • 2019-01-27
      • 2018-05-26
      • 2015-03-25
      相关资源
      最近更新 更多