gpt4 book ai didi

scala - 将元数据附加到 Spark 中的向量列

转载 作者:行者123 更新时间:2023-12-04 03:19:44 24 4
gpt4 key购买 nike

上下文:
我有一个包含两列的数据框:标签和特征。

org.apache.spark.sql.DataFrame = [label: int, features: vector]

其中 features 是使用 VectorAssembler 构建的数字类型的 mllib.linalg.VectorUDT。

问题:
有没有办法为特征向量分配模式?我想跟踪每个功能的名称。

到目前为止尝试过:
val defaultAttr = NumericAttribute.defaultAttr
val attrs = Array("feat1", "feat2", "feat3").map(defaultAttr.withName)
val attrGroup = new AttributeGroup("userFeatures", attrs.asInstanceOf[Array[Attribute]])
scala> attrGroup.toMetadata 
res197: org.apache.spark.sql.types.Metadata = {"ml_attr":{"attrs":{"numeric":[{"idx":0,"name":"f1"},{"idx":1,"name":"f2"},{"idx":2,"name":"f3"}]},"num_attrs":3}}

但不确定如何将其应用于现有数据框。

最佳答案

至少有两个选择:

  • 在现有 DataFrame您可以使用 as方法与 metadata争论:
    import org.apache.spark.ml.attribute._

    val rdd = sc.parallelize(Seq(
    (1, Vectors.dense(1.0, 2.0, 3.0))
    ))
    val df = rdd.toDF("label", "features")

    df.withColumn("features", $"features".as("_", attrGroup.toMetadata))
  • 创建新时 DataFrame转换 AttributeGroup toStructField并将其用作给定列的架构:
    import org.apache.spark.sql.types.{StructType, StructField, IntegerType}

    val schema = StructType(Array(
    StructField("label", IntegerType, false),
    attrGroup.toStructField()
    ))

    spark.createDataFrame(
    rdd.map(row => Row.fromSeq(row.productIterator.toSeq)),
    schema)

  • 如果使用 VectorAssembler 创建了向量列应该已经附加了描述父列的列元数据。
    import org.apache.spark.ml.feature.VectorAssembler

    val raw = sc.parallelize(Seq(
    (1, 1.0, 2.0, 3.0)
    )).toDF("id", "feat1", "feat2", "feat3")

    val assembler = new VectorAssembler()
    .setInputCols(Array("feat1", "feat2", "feat3"))
    .setOutputCol("features")

    val dfWithMeta = assembler.transform(raw).select($"id", $"features")
    dfWithMeta.schema.fields(1).metadata

    // org.apache.spark.sql.types.Metadata = {"ml_attr":{"attrs":{"numeric":[
    // {"idx":0,"name":"feat1"},{"idx":1,"name":"feat2"},
    // {"idx":2,"name":"feat3"}]},"num_attrs":3}

    矢量字段不能使用点语法直接访问(如 $features.feat1 ),但可以由专业工具使用,如 VectorSlicer :
    import org.apache.spark.ml.feature.VectorSlicer

    val slicer = new VectorSlicer()
    .setInputCol("features")
    .setOutputCol("featuresSubset")
    .setNames(Array("feat1", "feat3"))

    slicer.transform(dfWithMeta).show
    // +---+-------------+--------------+
    // | id| features|featuresSubset|
    // +---+-------------+--------------+
    // | 1|[1.0,2.0,3.0]| [1.0,3.0]|
    // +---+-------------+--------------+

    对于 PySpark,请参阅 How can I declare a Column as a categorical feature in a DataFrame for use in ml

    关于scala - 将元数据附加到 Spark 中的向量列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35305154/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com