2016-02-10 18 views
8

Bối cảnh: Tôi có khung dữ liệu có hai cột: nhãn và các đối tượng địa lý.Đính kèm siêu dữ liệu vào cột vectơ trong Spark

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

đâu tính năng là một mllib.linalg.VectorUDT kiểu số được xây dựng sử dụng VectorAssembler.

Câu hỏi: Có cách nào để chỉ định giản đồ cho vectơ tính năng không? Tôi muốn theo dõi tên của từng tính năng.

Cố gắng cho đến nay:

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}} 

Nhưng không chắc làm thế nào để áp dụng điều này để một khung dữ liệu hiện có.

Trả lời

9

Có lúc vì sợ hai lựa chọn:

  1. On hiện DataFrame bạn có thể sử dụng as phương pháp với metadata luận:

    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)) 
    
  2. Khi bạn tạo mới DataFrame chuyển đổi AttributeGrouptoStructField và sử dụng nó như một giản đồ cho một cột nhất định:

    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) 
    

Nếu cột vectơ được tạo bằng cách sử dụng VectorAssembler siêu dữ liệu cột mô tả cột mẹ phải được đính kèm.

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} 

lĩnh vực Vector không trực tiếp tiếp cận sử dụng dấu chấm cú pháp (như $features.feat1) nhưng có thể được sử dụng bởi các công cụ chuyên ngành như 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]| 
// +---+-------------+--------------+ 

Đối PySpark thấy How can I declare a Column as a categorical feature in a DataFrame for use in ml

+1

thể là "feat1" cột được trích xuất bằng tên thay vì chỉ mục? – gstvolvr

+0

Loại. Bạn có thể sử dụng 'VectorSlicer'. – zero323

+0

OK. Cảm ơn bạn! – gstvolvr

Các vấn đề liên quan