特征处理1_StringIndexer与OneHotEncoder

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了特征处理1_StringIndexer与OneHotEncoder相关的知识,希望对你有一定的参考价值。

参考技术A

字符串-索引变换,就是将某些标签的字符串列编号变成标签索引项。标签索引项序列的取值范围就是
[0,numLabels](这里的numLabels是所有出现的单词去掉重复的词后的总和)。
这里的标签索引项顺序就是按照标签出现的频率来排序的,出现最多的标签索引就是0(倒序)。
如果输入是数值型,先将数值映射到字符串,再对字符串进行索引化

与StringIndexer对应,IndexToString是将索引化标签还原成原始的字符串。
使用场景:在通过StringIndexer产生索引化标签,然后使用索引化标签进行训练,最后对预测结果使用IndexToString来获取其原始的标签字符串。

结果显示:

StringIndexer还有一个setHandleInvalid()的方法,通常是因为构建了一个StringIndexer实例,对DataFrame1进行fit后,再对DataFrame2进行transform,DataFrame2中出现了DataFrame1中未曾出现的标签,这时候可以通过设置setHandleInvalid(“skip”)来忽略新标签的行;
当然setHandleInvalid(“keep”)则保留。

不过奇怪的是,在实际工作中,发现fit和transform同一个Dataframe时,也有可能报这个错

可以将离散特征通过one-hot编码映射到欧式空间,而我们常用的距离或相似度的计算都是基于欧式空间的。
将一列标签索引映射到一列二进制向量,最多只会有一个单值(只有一个1)。
如果是有4个标签索引:1,2,3,4
那么对应的One-hot为[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]

结果显示:

注意:有一个方法 setDropLast,是否丢弃最后一个数,默认为true,观察上面的结果发现categoryIndex最大的2.0,经过OneHot得到的categoryVec为(2,[],[]),最大的categoryIndex被丢弃了。

不过在设置setDropLast(false)后,

Spark ml pipeline - transforming feature - StringIndexer

在spark ml pipeline的特征提取和转换阶段,有一种transformer可以将机器学习训练数据中常见的字符串列(例如表示各种分类)转换为数值索引列,以便于计算机处理。它就是StringIndexer。它支持的索引范围为[0, numLabels)(不支持的会编码为numLabels),并且支持四种排序方式,frequencyDesc(频率最高的索引赋值为0),frequencyAsc,alphabetDesc,alphabetAsc。

 

假设我们有dataframe

 id | category
----|----------
 0  | a
 1  | b
 2  | c
 3  | a
 4  | a
 5  | c

 

应用索引器 将category作为input 将categoryIndex作为output

 id | category | categoryIndex
----|----------|---------------
 0  | a        | 0.0
 1  | b        | 2.0
 2  | c        | 1.0
 3  | a        | 0.0
 4  | a        | 0.0
 5  | c        | 1.0

“a” gets index 0 because it is the most frequent, followed by “c” with index 1 and “b” with index 2.

 

当StringIndexer遇到之前没有处理过的字符串时,对于新数据有三种处理策略

  • 抛出异常 (默认)
  • 跳过当前行
  • 放置未知标签

 

如果我们使用之前生成的StringIndexer 应用于以下数据

 id | category
----|----------
 0  | a
 1  | b
 2  | c
 3  | d
 4  | e

 

如果没有设置未知策略,或者设置为error策略,都会抛出异常,然后如果设置过setHandleInvalid("skip") 将会跳过d,e所在行

id | category | categoryIndex
----|----------|---------------
 0  | a        | 0.0
 1  | b        | 2.0
 2  | c        | 1.0

 

如果调用setHandleInvalid("keep") 将会生成如下数据

id | category | categoryIndex
----|----------|---------------
 0  | a        | 0.0
 1  | b        | 2.0
 2  | c        | 1.0
 3  | d        | 3.0
 4  | e        | 3.0

注意: “d” or “e” 所在行 都被映射为索引 “3.0”, keep设置了未知编码,而不是继续编码

 

scala代码示例:

import org.apache.spark.ml.feature.StringIndexer

//创建表 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让indexer编码df索引 然后对某一个表进行转换 这里还是本身 不会抛出异常 或者跳过 val indexed
= indexer.fit(df).transform(df) indexed.show()

 

详细API见文档 https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.ml.feature.StringIndexer

 

ref: https://spark.apache.org/docs/latest/ml-features.html#stringindexer

 

以上是关于特征处理1_StringIndexer与OneHotEncoder的主要内容,如果未能解决你的问题,请参考以下文章

特征抽取--标签与索引的转化: VectorIndexer

Spark2.0 特征提取转换选择之二:特征选择文本处理,以中文自然语言处理(情感分类)为例

spark过滤算子+StringIndexer算子出发的一个逻辑bug

机器学习系列_从白富美相亲看特征预处理与选择(下)

[机器学习与scikit-learn-47]:特征工程-sklearn中的数据预处理和特征工程概述

Spark StringIndexer和IndexToString