Spark机器学习API之特征处理(二)

Spark机器学习库中包含了两种实现方式,一种是spark.mllib,这种是基础的API,基于RDDs之上构建,另一种是spark.ml,这种是higher-level API,基于DataFrames之上构建,spark.ml使用起来比较方便和灵活。

Spark机器学习中关于特征处理的API主要包含三个方面:特征提取、特征转换与特征选择。本文通过例子介绍和学习Spark.ml中提供的关于特征处理API中的特征选择(Feature Selectors)部分。

特征选择(Feature Selectors)

1.  VectorSlicer

VectorSlicer用于从原来的特征向量中切割一部分,形成新的特征向量,比如,原来的特征向量长度为10,我们希望切割其中的5~10作为新的特征向量,使用VectorSlicer可以快速实现。

大数据/机器学习交流群:724693112 欢迎大家一起交流学习~

package com.lxw1234.spark.features.selectors


import org.apache.spark.SparkConf

import org.apache.spark.SparkContext


import org.apache.spark.ml.attribute.{Attribute, AttributeGroup, NumericAttribute}

import org.apache.spark.ml.feature.VectorSlicer

import org.apache.spark.mllib.linalg.Vectors

import org.apache.spark.sql.Row

import org.apache.spark.sql.types.StructType


/**

* By  http://lxw1234.com

*/

object TestVectorSlicer extends App {

    val conf = new SparkConf().setMaster("local").setAppName("lxw1234.com")

    val sc = new SparkContext(conf)


    val sqlContext = new org.apache.spark.sql.SQLContext(sc)

    import sqlContext.implicits._



    //构造特征数组

    val data = Array(Row(Vectors.dense(-2.0, 2.3, 0.0)))


    //为特征数组设置属性名(字段名),分别为f1 f2 f3

    val defaultAttr = NumericAttribute.defaultAttr

    val attrs = Array("f1", "f2", "f3").map(defaultAttr.withName)

    val attrGroup = new AttributeGroup("userFeatures", attrs.asInstanceOf[Array[Attribute]])


    //构造DataFrame

    val dataRDD = sc.parallelize(data)

    val dataset = sqlContext.createDataFrame(dataRDD, StructType(Array(attrGroup.toStructField())))


    print("原始特征:")

    dataset.take(1).foreach(println)



    //构造切割器

    var slicer = new VectorSlicer().setInputCol("userFeatures").setOutputCol("features")


    //根据索引号,截取原始特征向量的第1列和第3列

    slicer.setIndices(Array(0,2))

    print("output1: ")

    slicer.transform(dataset).select("userFeatures", "features").first()


    //根据字段名,截取原始特征向量的f2和f3

    slicer = new VectorSlicer().setInputCol("userFeatures").setOutputCol("features")

    slicer.setNames(Array("f2","f3"))

    print("output2: ")

    slicer.transform(dataset).select("userFeatures", "features").first()


    //索引号和字段名也可以组合使用,截取原始特征向量的第1列和f2

    slicer = new VectorSlicer().setInputCol("userFeatures").setOutputCol("features")

    slicer.setIndices(Array(0)).setNames(Array("f2"))

    print("output3: ")

    slicer.transform(dataset).select("userFeatures", "features").first()



}

程序运行输出为:

原始特征:

[[-2.0,2.3,0.0]]


output1:

org.apache.spark.sql.Row = [[-2.0,2.3,0.0],[-2.0,0.0]]


output2:

org.apache.spark.sql.Row = [[-2.0,2.3,0.0],[2.3,0.0]]


output3:

org.apache.spark.sql.Row = [[-2.0,2.3,0.0],[-2.0,2.3]]


2.  RFormula

RFormula用于将数据中的字段通过R语言的Model Formulae转换成特征值,输出结果为一个特征向量和Double类型的label。关于R语言Model Formulae的介绍可参考:https://stat.ethz.ch/R-manual/R-devel/library/stats/html/formula.html

package com.lxw1234.spark.features.selectors


import org.apache.spark.SparkConf

import org.apache.spark.SparkContext


import org.apache.spark.ml.feature.RFormula


/**

* By  http://lxw1234.com

*/

object TestRFormula extends App {


    val conf = new SparkConf().setMaster("local").setAppName("lxw1234.com")

    val sc = new SparkContext(conf)


    val sqlContext = new org.apache.spark.sql.SQLContext(sc)

    import sqlContext.implicits._


    //构造数据集

    val dataset = sqlContext.createDataFrame(Seq(

      (7, "US", 18, 1.0),

      (8, "CA", 12, 0.0),

      (9, "NZ", 15, 0.0)

    )).toDF("id", "country", "hour", "clicked")

    dataset.select("id", "country", "hour", "clicked").show()


    //当需要通过country和hour来预测clicked时候,

    //构造RFormula,指定Formula表达式为clicked ~ country + hour

    val formula = new RFormula().setFormula("clicked ~ country + hour").setFeaturesCol("features").setLabelCol("label")

    //生成特征向量及label

    val output = formula.fit(dataset).transform(dataset)

    output.select("id", "country", "hour", "clicked", "features", "label").show()


}

程序输出:



3.  ChiSqSelector

ChiSqSelector用于使用卡方检验来选择特征(降维)。

package com.lxw1234.spark.features.selectors


import org.apache.spark.SparkConf

import org.apache.spark.SparkContext

import org.apache.spark.ml.feature.ChiSqSelector

import org.apache.spark.mllib.linalg.Vectors


/**

* By  http://lxw1234.com

*/

object TestChiSqSelector extends App {


    val conf = new SparkConf().setMaster("local").setAppName("lxw1234.com")

    val sc = new SparkContext(conf)


    val sqlContext = new org.apache.spark.sql.SQLContext(sc)

    import sqlContext.implicits._


    //构造数据集

    val data = Seq(

      (7, Vectors.dense(0.0, 0.0, 18.0, 1.0), 1.0),

      (8, Vectors.dense(0.0, 1.0, 12.0, 0.0), 0.0),

      (9, Vectors.dense(1.0, 0.0, 15.0, 0.1), 0.0)

    )

    val df = sc.parallelize(data).toDF("id", "features", "clicked")

    df.select("id", "features","clicked").show()


    //使用卡方检验,将原始特征向量(特征数为4)降维(特征数为3)

    val selector = new ChiSqSelector().setNumTopFeatures(3).setFeaturesCol("features").setLabelCol("clicked").setOutputCol("selectedFeatures")


    val result = selector.fit(df).transform(df)

    result.show()


}

程序输出为:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容