OneHotEncoder介绍单属性多属性scala实现

       因为项目的需要,将数据库中表的属性向量化,然后进行机器学习,所以去spark官网学习了一下OneHotEncoder,官网的相关介绍比较少,主要是针对单属性的处理,但是项目的要求是多属性的处理,网上找了很多的资料,研究了大半天终于将它集成到了自己的项目之中,下面分享一下自己的学习心得,说的不好的地方,还请各位大神多多指教。

      介绍:将类别映射为二进制向量,其中至多一个值为1(其余为零),这种编码可供期望连续特征的算法使用,比如逻辑回归,这些分类的算法。

     好处:1.解决分类器不好处理属性数据的问题(分类器往往默认数据是连续的,并且是有序的)

                2.在一定程度上也起到了扩充特征的作用

     原理:1.String字符串转换成索引IndexDouble

                2.索引转化成SparseVector

      总结:OneHotEncoder=String->IndexDouble->SparseVector

单属性的官网实现:

package com.iflytek.features import org.apache.spark.ml.feature.{OneHotEncoder, StringIndexer} import org.apache.spark.ml.feature.{IndexToString, StringIndexer} import org.apache.spark.sql.SparkSession import org.apache.spark.ml.linalg.SparseVector

object OneHotEncoder {   val spark=SparkSession.builder().appName("pca").master("local").getOrCreate()   def main(args: Array[String]): Unit = {   val df = spark.createDataFrame(Seq(   (0, "a"),   (1, "b"),   (2, "c"),   (3, "a"),   (4, "a"),   (5, "c")   )).toDF("id", "category")

  //可以把一个属性列里的值映射成数值类型   val indexer = new StringIndexer()     .setInputCol("category")     .setOutputCol("categoryIndex")     .fit(df)   val indexed = indexer.transform(df)

  indexed.select("category", "categoryIndex").show()

  val encoder = new OneHotEncoder()     .setInputCol("categoryIndex")     .setOutputCol("categoryVec")   val encoded = encoder.transform(indexed)   encoded.select("id","categoryIndex", "categoryVec").show()   encoded.select("categoryVec").foreach {     x => println(x.getAs[SparseVector]("categoryVec").toArray.foreach {       x => print(x+" ")       }     )     }     } }

输出结果如下:

+--------+-------------+ |category|categoryIndex| +--------+-------------+ |       a|          0.0| |       b|          2.0| |       c|          1.0| |       a|          0.0| |       a|          0.0| |       c|          1.0| +--------+-------------+

+---+-------------+-------------+ | id|categoryIndex|  categoryVec| +---+-------------+-------------+ |  0|          0.0|(2,[0],[1.0])| |  1|          2.0|    (2,[],[])| |  2|          1.0|(2,[1],[1.0])| |  3|          0.0|(2,[0],[1.0])| |  4|          0.0|(2,[0],[1.0])| |  5|          1.0|(2,[1],[1.0])| +---+-------------+-------------+

1.0 0.0 () 0.0 0.0 () 0.0 1.0 () 1.0 0.0 () 1.0 0.0 () 0.0 1.0 ()

多属性的找了很多资料,业务需求一般都是多属性的:

import  sc.implicits._     val vectorData = dataRDD       //将 枚举的值 转化为 Double      .map( x => (  enum2Double("是否已流失",x._1),   x._2(0) , x._2(1) ,x._2(2),x._2(3) ) )        //ml.feature.LabeledPoint      .toDF("loss","gender","age","grade","region")

     //indexing columns     val stringColumns = Array("gender","age","grade","region")     val index_transformers: Array[org.apache.spark.ml.PipelineStage] = stringColumns.map(     cname => new StringIndexer()         .setInputCol(cname)         .setOutputCol(s"${cname}_index")      )

    // Add the rest of your pipeline like VectorAssembler and algorithm     val index_pipeline = new Pipeline().setStages(index_transformers)     val index_model = index_pipeline.fit(vectorData)     val df_indexed = index_model.transform(vectorData)

    //encoding columns     val indexColumns  = df_indexed.columns.filter(x => x contains "index")     val one_hot_encoders: Array[org.apache.spark.ml.PipelineStage] = indexColumns.map(     cname => new OneHotEncoder()        .setInputCol(cname)        .setOutputCol(s"${cname}_vec")     )

    val pipeline = new Pipeline().setStages(index_transformers ++ one_hot_encoders)

    val model = pipeline.fit(vectorData)

model.transform(vectorData).select("loss","gender_index_vec","age_index_vec","grade_index_vec","region_index_vec")     .map (         x=>         ml.feature.LabeledPoint(x.apply(0).toString().toDouble ,ml.linalg.Vectors.dense(x.getAs[SparseVector]    ("gender_index_vec").toArray++x.getAs[SparseVector]("age_index_vec").toArray++x.getAs[SparseVector]("grade_index_vec").toArray++x.getAs[SparseVector]("region_index_vec").toArray))      )

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

2000 楼房重建 2012年

 时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题解  查看运行结果 题目描述 Description   小A的楼...

3477
来自专栏程序生活

文本特征提取Bag of words(词袋)tfidfcsr_matrix

其实我比较疑惑的地方是toarray()这个方法,count_data 为什么可以通过这个方法可以转化成那个样子,后来查了一下资料: 下面是一个关于csr_m...

752
来自专栏ACM算法日常

四两拨千斤,GCC编译器(同余模) - HDU 3123

同余这一属性看起来简单,然而却是数论中极为重要的概念。与之相关的公式和定理更是纷繁芜杂,如果不是数学背景的童鞋,恐怕很难深入去钻研所有的知识。

662
来自专栏数据结构与算法

BZOJ4514: [Sdoi2016]数字配对(费用流)

Description 有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。 若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/a...

3357
来自专栏PPV课数据科学社区

【学习】笨办法学R编程(四)

随着教程推进,基本的语法都接触得差不多了。当要解决某个具体问题时,只需要考虑用什么样的算法来整合运用这些函数和表达式。今天来解决Project ...

2674
来自专栏懒人开发

(5.5)James Stewart Calculus 5th Edition:The Substitution Rule

注意: 这里 自变量改变,对应范围也会改变 不定积分的上下限,由 [a, b] 变为了 [g(a), g(b)]

783
来自专栏菩提树下的杨过

Flash/Flex学习笔记(43):动量守恒与能量守恒

动能公式: ? 动量公式: ? 动量守恒: ? 能量守恒: ? 根据这些规律可以得到下列方程组: ? ? 解该方程组,得到下面的公式: ? ? 把这二个公式相...

1827
来自专栏WOLFRAM

用 Wolfram 语言来做2017年高考数学试题之新课标Ⅲ理科卷

2094
来自专栏小樱的经验随笔

图论----同构图(详解)

图论当中的术语,假设G=(V,E)和G1=(V1,E1)是两个图,如果存在一个双射m:V→V1,使得对所有的x,y∈V均有xy∈E等价于m(x)m(y)∈E1,...

4158
来自专栏ACM算法日常

当七夕遇上算法竞赛

  七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去T...

862

扫码关注云+社区