文章目录
- 特征转换方法
- StringIndexer
- VectorIndexer
- IndexToString
- 一、StringIndexer
- 二、IndexToString
- 三、VectorIndexer
- 离散<->连续特征或Label相互转换
- oneHotEncoder
- Bucketizer
- 输出
- 例子
- 决策树简介
- 运行实例
- 结果展示
特征转换方法
StringIndexer
StringIndexer(字符串-索引变换)是一个估计器,是将字符串列编码为标签索引列。索引位于[0,numLabels),按标签频率排序,频率最高的排0,依次类推,因此最常见的标签获取索引是0。
VectorIndexer
VectorIndexer(向量-索引变换)是一种估计器,能够提高决策树或随机森林等ML方法的分类效果,是对数据集特征向量中的类别(离散值)特征进行编号。它能够自动判断哪些特征是离散值型的特征,并对他们进行编号。
IndexToString
IndexToString(索引-字符串变换)是一种转换器,与StringIndexer对应,能将指标标签映射回原始字符串标签。一个常见的用例(下文的例子就是如此)是使用StringIndexer从标签生成索引,使用这些索引训练模型,并从IndexToString的预测索引列中检索原始标签。
一、StringIndexer
- StringIndexer本质上是对String类型–>index( number);
- 如果是:数值(numeric)–>index(number),实际上是对把数值先进行了类型转换( cast numeric to string and then index the string values.),也就是说无论是String,还是数值,都可以重新编号(Index);
- 利用获得的模型转化新数据集时,可能遇到异常情况
在使用Spark MLlib协同过滤ALS API的时候发现Rating的三个参数:用户id,商品名称,商品打分,前两个都需要是Int值。那么问题来了,当你的用户id,商品名称是String类型的情况下,我们必须寻找一个方法可以将海量String映射为数字类型。好在Spark MLlib可以answer这一切。
StringIndexer 将一列字符串标签编码成一列下标标签,下标范围在[0, 标签数量),顺序是标签的出现频率。所以最经常出现的标签获得的下标就是0。如果输入列是数字的,我们会将其转换成字符串,然后将字符串改为下标。当下游管道组成部分,比如说Estimator 或Transformer 使用将字符串转换成下标的标签时,你必须将组成部分的输入列设置为这个将字符串转换成下标后的列名。很多情况下,你可以使用setInputCol设置输入列。
此外,当你针对一个数据集训练了一个StringIndexer,然后使用其去transform另一个数据集的时候,针对不可见的标签StringIndexer 有两个应对策略:
针对训练集中没有出现的字符串值,spark提供了几种处理的方法:
error,直接抛出异常
skip,跳过该样本数据( skip the row containing the unseen label entirely跳过包含不可见标签的这一行)
keep,使用一个新的最大索引,来表示所有未出现的值
throw an exception (which is the default)默认是抛出异常
二、IndexToString
IndexToString 和StringIndexer是对称的,它将一列下标标签映射回一列包含原始字符串的标签。常用的场合是使用StringIndexer生产下标,通过这些下标训练模型,通过IndexToString从预测出的下标列重新获得原始标签。不过,你也可以使用你自己的标签。
输出
三、VectorIndexer
主要作用:提高决策树或随机森林等ML方法的分类效果。
VectorIndexer是对数据集特征向量中的类别(离散值)特征(index categorical features categorical features )进行编号。
它能够自动判断那些特征是离散值型的特征,并对他们进行编号,具体做法是通过设置一个maxCategories,特征向量中某一个特征不重复取值个数小于maxCategories,则被重新编号为0~K(K<=maxCategories-1)。某一个特征不重复取值个数大于maxCategories,则该特征视为连续值,不会重新编号(不会发生任何改变)。
离散<->连续特征或Label相互转换
oneHotEncoder
独热编码将类别特征(离散的,已经转换为数字编号形式),映射成独热编码。这样在诸如Logistic回归这样需要连续数值值作为特征输入的分类器中也可以使用类别(离散)特征。
独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位 状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器 位,并且在任意时候,其 中只有一位有效。
例如: 自然状态码为:000,001,010,011,100,101
独热编码为:000001,000010,000100,001000,010000,100000
可以这样理解,对于每一个特征,如果它有m个可能值,那么经过独 热编码后,就变成了m个二元特征。并且,这些特征互斥,每次只有 一个激活。因此,数据会变成稀疏的。
这样做的好处主要有:
解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用
Bucketizer
分箱(分段处理):将连续数值转换为离散类别
比如特征是年龄,是一个连续数值,需要将其转换为离散类别(未成年人、青年人、中年人、老年人),就要用到Bucketizer了。
分类的标准是自己定义的,在Spark中为split参数,定义如下:
double[] splits = {0, 18, 35,50, Double.PositiveInfinity}
将数值年龄分为四类0-18,18-35,35-50,55+四个段。
如果左右边界拿不准,就设置为,Double.NegativeInfinity, Double.PositiveInfinity,不会有错的。
输出
QuantileDiscretizer
分位树为数离散化,和Bucketizer(分箱处理)一样也是:将连续数值特征转换为离散类别特征。实际上Class QuantileDiscretizer extends (继承自) Class(Bucketizer)。
参数1:不同的是这里不再自己定义splits(分类标准),而是定义分几箱(段)就可以了。QuantileDiscretizer自己调用函数计算分位数,并完成离散化。
-参数2: 另外一个参数是精度,如果设置为0,则计算最精确的分位数,这是一个高时间代价的操作。另外上下边界将设置为正负无穷,覆盖所有实数范围。
例子
决策树简介
决策树是一种树形结构,由节点和有向边组成。节点有两种类型:内部节点和叶节点,内部节点代表一个特征或属性,叶节点代表一个类。每个非叶节点代表一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出。使用决策树进行决策的过程就是从根节点开始,测试待分类项中的相应属性,按照其值选择输出分支,直到达到叶节点,将叶节点存放的类别作为决策结果。
决策树算法本质上是从训练数据集上归纳出一组分类规则,遵循局部最优原则。即每次选择分类特征时,都挑选当前条件下最优的那个特征作为划分规则。
具体原理介绍读者可自行参考机器学习类相关书籍资料。
主要参数有:
- impurity 信息增益的计算标准,默认为“gini”
- maxBins 树的最大高度,默认为5
- maxDepth 用于分裂特征的最大划分量,默认为32
运行实例
数据说明
数据为LIBSVM格式文本文件
数据格式为:标签 特征ID:特征值 特征ID:特征值……
内容如下:
代码及相关说明
结果展示