1.1 StringIndexer简介
字符串-索引变换,就是将某些标签的字符串列编号变成标签索引项。标签索引项序列的取值范围就是
[0,numLabels](这里的numLabels是所有出现的单词去掉重复的词后的总和)。
这里的标签索引项顺序就是按照标签出现的频率来排序的,出现最多的标签索引就是0(倒序)。
如果输入是数值型,先将数值映射到字符串,再对字符串进行索引化。
1.2 IndexToString简介
与StringIndexer对应,IndexToString是将索引化标签还原成原始的字符串。
使用场景:在通过StringIndexer产生索引化标签,然后使用索引化标签进行训练,最后对预测结果使用IndexToString来获取其原始的标签字符串。
1.3 demo代码
val spark = SparkSession.builder()
.master("local[2]")
.appName("Spark Mllib")
.getOrCreate()
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.show(false)
//IndexToString案例
val converter=new IndexToString()
.setInputCol("categoryIndex")
.setOutputCol("originalCategory")
val converted=converter.transform(indexed)
converted.show(false)
结果显示:

StringIndexer还有一个setHandleInvalid()的方法,通常是因为构建了一个StringIndexer实例,对DataFrame1进行fit后,再对DataFrame2进行transform,DataFrame2中出现了DataFrame1中未曾出现的标签,这时候可以通过设置setHandleInvalid(“skip”)来忽略新标签的行;
当然setHandleInvalid(“keep”)则保留。
不过奇怪的是,在实际工作中,发现fit和transform同一个Dataframe时,也有可能报这个错
2.1 OneHotEncoder简介
可以将离散特征通过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]
2.2 demo演示
val spark = SparkSession.builder()
.master("local[2]")
.appName("Spark Mllib")
.getOrCreate()
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.show(false)
//OneHot
val encoder=new OneHotEncoder()
.setInputCol("categoryIndex")
.setOutputCol("categoryVec")
val encoded=encoder.transform(indexed)
encoded.show(false)
结果显示:

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