VectorSlicer

  VectorSlicer是一个转换器,输入一个特征向量输出一个特征向量,它是原特征的一个子集。这在从向量列中抽取特征非常有用。
VectorSlicer接收一个拥有特定索引的特征列,它的输出是一个新的特征列,它的值通过输入的索引来选择。有两种类型的索引:

  • 1、整数索引表示进入向量的索引,调用setIndices()
  • 2、字符串索引表示进入向量的特征列的名称,调用setNames()。这种情况需要向量列拥有一个AttributeGroup,这是因为实现是通过属性的名字来匹配的。

  整数和字符串都是可以使用的,并且,整数和字符串可以同时使用。至少需要选择一个特征,而且重复的特征是不被允许的。

  输出向量首先会按照选择的索引进行排序,然后再按照选择的特征名进行排序。

例子

  假设我们有下面的DataFrame,它的列名是userFeatures

  1. userFeatures
  2. ------------------
  3. [0.0, 10.0, 0.5]

  userFeatures是一个向量列,它包含三个用户特征。假设用户特征的第一列均为0,所以我们想删除它,仅仅选择后面的两列。
VectorSlicer通过setIndices(1,2)选择后面的两项,产生下面新的名为features的向量列。

  1. userFeatures | features
  2. ------------------|-----------------------------
  3. [0.0, 10.0, 0.5] | [10.0, 0.5]

  假设我们还有潜在的输入特性,如["f1", "f2", "f3"],我们还可以通过setNames("f2", "f3")来选择。

  1. userFeatures | features
  2. ------------------|-----------------------------
  3. [0.0, 10.0, 0.5] | [10.0, 0.5]
  4. ["f1", "f2", "f3"] | ["f2", "f3"]

  下面是程序调用的例子。

  1. import java.util.Arrays
  2. import org.apache.spark.ml.attribute.{Attribute, AttributeGroup, NumericAttribute}
  3. import org.apache.spark.ml.feature.VectorSlicer
  4. import org.apache.spark.ml.linalg.Vectors
  5. import org.apache.spark.sql.Row
  6. import org.apache.spark.sql.types.StructType
  7. val data = Arrays.asList(Row(Vectors.dense(-2.0, 2.3, 0.0)))
  8. val defaultAttr = NumericAttribute.defaultAttr
  9. val attrs = Array("f1", "f2", "f3").map(defaultAttr.withName)
  10. val attrGroup = new AttributeGroup("userFeatures", attrs.asInstanceOf[Array[Attribute]])
  11. val dataset = spark.createDataFrame(data, StructType(Array(attrGroup.toStructField())))
  12. val slicer = new VectorSlicer().setInputCol("userFeatures").setOutputCol("features")
  13. slicer.setIndices(Array(1)).setNames(Array("f3"))
  14. // or slicer.setIndices(Array(1, 2)), or slicer.setNames(Array("f2", "f3"))
  15. val output = slicer.transform(dataset)
  16. println(output.select("userFeatures", "features").first())