Spark MLlib中的OneHot哑变量实践

在机器学习中,线性回归和逻辑回归算是最基础入门的算法,很多书籍都把他们作为第一个入门算法进行介绍。除了本身的公式之外,逻辑回归和线性回归还有一些必须要了解的内容。一个很常用的知识点就是虚拟变量(也叫做哑变量)—— 用于表示一些无法直接应用到线性公式中的变量(特征)。

举个例子:

通过身高来预测体重,可以简单的通过一个线性公式来表示,y=ax+b。其中x为身高,y为体重。

现在想要多加一些特征(参数),比如性别。

那么问题来了:如何在一个公式中表示性别呢?

这就是哑变量的作用,它可以通过扩展特征值的个数来表示一些无法被直接数值化的参数。

实例演示

下面是一组数据,第一列表示体重,第二列表示身高,第三列表示性别

体重 身高 性别
60 170 F
45 163 M
80 183 F
70 175 F
52 167 M

现在首先需要把第三列转换成数值类型

体重 身高 性别
60 170 1.0
45 163 0.0
80 183 1.0
70 175 1.0
52 167 0.0

然后使用多维的数据表示这个参数

体重 身高 性别男 性别女
60 170 1.0 0.0
45 163 0.0 1.0
80 183 1.0 0.0
70 175 1.0 0.0
52 167 0.0 1.0

即,性别这一列会通过两列来标识。

一般来说,有多少种情况出现,就会出现多少列。当然会有很多不同的表现形式,比如有的是通过N-1列表示(为空时表示一种情况),有的是通过n列表示。

代码实践

在Spark MLlib中已经提供了处理哑变量的方法,叫做OneHotEncoder,翻译过来叫做 一位有效编码,即把可能出现多个值的某列转变成多列,同时只有一列有效。MLlib提供了两个方法一个是StringIndex方法,这个方法可以把不同的字符串转换成数值,比如F``M分别用0.0``1.0表示。还有一个是OneHotEncoder方法,这个方法可以把不同的数值转变成稀疏向量。

什么是稀疏向量

在MLlib中,向量有两种表示方法,一种是密集向量,一种是稀疏向量。

  • 密集向量很好理解,[1,2,3,4],代表这个向量有四个元素,分别是1 2 3 4
  • 稀疏向量则可以根据下表表示,(3,[4,5,6],[1,2,3]),第一个值代表大小,第二个代表下标数组,第二个是下标对应的值。

然后话说回来,OneHotEncoder方法可以把不同的数值变成稀疏向量,这样一列就相当于可以用多列来表示。

下面我们具体的看一下代码吧!

object encoderTest {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("MovieLensALS-Test").setMaster("local[2]")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")
    val sqlContext = new SQLContext(sc)
    val df = sqlContext.createDataFrame(Seq(
      (60, 170,"F","长春"),
      (45, 163,"M","长春"),
      (80, 183,"F","沈阳"),
      (70, 175,"F","大连"),
      (52, 167,"M","哈尔滨")
    )).toDF("weight", "height","sex","address")

    //把性别这一列数值化
    val indexer = new StringIndexer()
      .setInputCol("sex")
      .setOutputCol("sexIndex")
      .fit(df)
    val indexed = indexer.transform(df)
    //对性别这列进行 有效位编码
    val encoder = new OneHotEncoder()
      .setInputCol("sexIndex")
      .setOutputCol("sexVec")
    val encoded = encoder.transform(indexed)
    //对地址这一列数值化
    val indexer1 = new StringIndexer()
      .setInputCol("address")
      .setOutputCol("addressIndex")
      .fit(encoded)
    val indexed1 = indexer1.transform(encoded)
    //对地址进行有效位编码
    val encoder1 = new OneHotEncoder()
      .setInputCol("addressIndex")
      .setOutputCol("addressVec")
    val encoded1 = encoder1.transform(indexed1)

    encoded1.show()
  }
}

输出的内容为:

+------+------+---+-------+--------+-------------+------------+-------------+
|weight|height|sex|address|sexIndex|       sexVec|addressIndex|   addressVec|
+------+------+---+-------+--------+-------------+------------+-------------+
|    60|   170|  F|     长春|     0.0|(1,[0],[1.0])|         0.0|(3,[0],[1.0])|
|    45|   163|  M|     长春|     1.0|    (1,[],[])|         0.0|(3,[0],[1.0])|
|    80|   183|  F|     沈阳|     0.0|(1,[0],[1.0])|         3.0|    (3,[],[])|
|    70|   175|  F|     大连|     0.0|(1,[0],[1.0])|         2.0|(3,[2],[1.0])|
|    52|   167|  M|    哈尔滨|     1.0|    (1,[],[])|         1.0|(3,[1],[1.0])|
+------+------+---+-------+--------+-------------+------------+-------------+

这样有什么用呢?
得到了weight``height``sexVec``addressVec,就相当于得到了一组数据,基于这组数据,就可以来训练线性回归,得到模型后,就可以根据一个人的身高、性别、地址来预测这个人的身高了。

参考

1 MLlib OneHotEncoder官方文档:http://spark.apache.org/docs/1.6.0/ml-features.html#onehotencoder
2 虚拟变量定义:http://wiki.mbalib.com/wiki/%E8%99%9A%E6%8B%9F%E5%8F%98%E9%87%8F

本文转自博客园xingoo的博客,原文链接:Spark MLlib中的OneHot哑变量实践,如需转载请自行联系原博主。

时间: 2024-10-25 20:53:14

Spark MLlib中的OneHot哑变量实践的相关文章

Apache Spark源码走读(十一)浅谈mllib中线性回归的算法实现&Spark MLLib中拟牛顿法L-BFGS的源码实现

<一>浅谈mllib中线性回归的算法实现 概要 本文简要描述线性回归算法在Spark MLLib中的具体实现,涉及线性回归算法本身及线性回归并行处理的理论基础,然后对代码实现部分进行走读. 线性回归模型 机器学习算法是的主要目的是找到最能够对数据做出合理解释的模型,这个模型是假设函数,一步步的推导基本遵循这样的思路 假设函数 为了找到最好的假设函数,需要找到合理的评估标准,一般来说使用损失函数来做为评估标准 根据损失函数推出目标函数 现在问题转换成为如何找到目标函数的最优解,也就是目标函数的最

Spark MLlib中的协同过滤

本文主要通过Spark官方的例子理解ALS协同过滤算法的原理和编码过程,然后通过对电影进行推荐来熟悉一个完整的推荐过程. 协同过滤 协同过滤常被应用于推荐系统,旨在补充用户-商品关联矩阵中所缺失的部分.MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐语义因子进行表达,并且这些因子也用于预测缺失的元素.Spark MLlib实现了交替最小二乘法(ALS) 来学习这些隐性语义因子. 在 MLlib 中的实现类为org.apache.spark.mllib.recommendation

spark MLlib中协同过滤算法接受的userId是int类型,但是真正的ID是字符串,怎么映射好呢?

问题描述 MLlib的cf算法接受的是Rating类型的RDD:JavaRDD<Rating>其中Rating代表的是两个int和一个doubleorg.apache.spark.mllib.recommendation.Rating.Rating(intuser,intproduct,doublerating)但是假如我的用户唯一标识是uuid,那么怎么转换成唯一对应的int类型?直接弄个映射表把1234和uuid对应起来么? 解决方案 解决方案二:额,大家都没碰到过这个问题么?解决方案三:

在spark streaming中实时更新mllib的ALS算法的模型遇到的问题!

问题描述 在spark streaming中实时更新mllib的ALS算法的模型遇到的问题! 在spark streaming中使用ALS算法,实现模型的实时更新有人了解吗? 总是出ERROR [dag-scheduler-event-loop] scheduler.DAGSchedulerEventProcessLoop (Logging.scala:logError(96)) - DAGSchedulerEventProcessLoop failed; shutting down Spark

推荐系统那点事 —— 基于Spark MLlib的特征选择

在机器学习中,一般都会按照下面几个步骤:特征提取.数据预处理.特征选择.模型训练.检验优化.那么特征的选择就很关键了,一般模型最后效果的好坏往往都是跟特征的选择有关系的,因为模型本身的参数并没有太多优化的点,反而特征这边有时候多加一个或者少加一个,最终的结果都会差别很大. 在SparkMLlib中为我们提供了几种特征选择的方法,分别是VectorSlicer.RFormula和ChiSqSelector. 下面就介绍下这三个方法的使用,强烈推荐有时间的把参考的文献都阅读下,会有所收获! Vect

开源大数据技术专场(上午):Spark、HBase、JStorm应用与实践

16日上午9点,2016云栖大会"开源大数据技术专场" (全天)在阿里云技术专家封神的主持下开启.通过封神了解到,在上午的专场中,阿里云高级技术专家无谓.阿里云技术专家封神.阿里巴巴中间件技术部高级技术专家天梧.阿里巴巴中间件技术部资深技术专家纪君祥将给大家带来Hadoop.Spark.HBase.JStorm Turbo等内容. 无谓:Hadoop过去现在未来,从阿里云梯到E-MapReduce 阿里云高级技术专家 无谓  从开辟大数据先河至现在,风雨十年,Hadoop已成为企业的通

Spark生态系统中的图数据分析知识

图结构可有效表示稀疏矩阵,因而图数据分析可用于实现大数据分析.对于Spark生态系统中的图处理系统GraphX,<Spark GraphX in Action>一书给出了详细的教程和典型用例,将教会读者如何使用GraphX和GraphFrames进行图分析.本文是Info对该书作者的访谈,内容包括图数据及分析技术.GraphX高效程序开发.图数据分析的趋势等. 如何定义图数据? Michael Malak:就事论事,图结构看上去并非像股价图那样,而是边和点的集合.但这只是一种模糊的数学抽象.更

《Spark MLlib 机器学习实战》1——读后总结

1 概念 2 安装 3 RDD RDD包含两种基本的类型:Transformation和Action.RDD的执行是延迟执行,只有Action算子才会触发任务的执行. 宽依赖和窄依赖用于切分任务,如果都是窄依赖,那么就可以最大化的利用并行. 常用操作: cache 缓存 cartesian 笛卡尔积 coalesce 重分区 countByValue 分组统计 distinct 去除重复 filter 过滤 flatMap map groupBy 分组 keyBy 增加key reduce 拼接

如果在SPARK函数中使用UDF或UDAF

Spark目前已经内置的函数参见: Spark 1.5 DataFrame API Highlights: Date/Time/String Handling, Time Intervals, and UDAFs 如果在SPARK函数中使用UDF或UDAF, 详见示例 package cn.com.systex import scala.reflect.runtime.universe import org.apache.spark.SparkConf import org.apache.spa