少なくとも 2 つのオプションがあります。
既存では、メソッドを引数とともに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 については、ML で使用する DataFrame のカテゴリ機能として列を宣言する方法を参照してください。