在Spark下进行机器学习,必然无法离开其提供的MLlib框架,所以接下来我们将以本框架为基础进行实际的讲解。首先我们需要了解其中最基本的结构类型,即转换器、估计器、评估器和流水线。
首先欢迎大家Start本人关于机器学习的学习仓库,不仅仅包含了Spark ML还包括python下的sklearn等主流库。
接下来我们将以一个简单的例子为基础整体介绍在Spark下进行机器学习的使用方式,便于读者大体熟悉完整的流程节点。当然在这其中对于部分不了解的情况下可以等在后续详细学习的过程中进行补充即可。
点击此处查看代码示例
这部分相关知识可以参考本人编写的人工智能专题的开源教程,其中对该部分进行详细的说明,下面我们将就框架提供的进行具体的实战操作(这里熟悉R语言的可能对此比较熟悉,本身就是借鉴了R语言,但是仅实现了其中的一个子集),对于我们需要进行特征化的数据首先我们需要定义对应的线性模型公式,具体如下。
当然仅仅通过上述的方式还不能实现对数据的特征化,我们还需要通过数据对其进行训练,从而得到我们所需的转换器,为此我们需要使用其中的方法进行转换。
完成转换器的训练后我们就可以利用其进行实际的转换操作,从而生成特征与标签列,当然读者也可以通过设置标签列名,设置特征列名。对于监督学习都需要将数据分为样本数据与测试数据,为此我们需要通过以下方式将数据拆分。
在Spark MLib中为估计器,这里我们将采用逻辑回归的算法做为演示,提供一个分类算法模型的训练,首先我们实例化我们需要的模型类,通过其提供的方式对将训练数据传入其中进行模型的训练。
如果在对数据进行特征工程的时候将标签以及特征列的名称进行了修改,那么我们也需要通过以及进行同步修改调整。同时框架也提供了方法打印模型中可供调整的参数。
对于机器学习,后期工作基本就是对各种参数的调优,为此Spark提供了友好的流水线,并基于其本平台分布式计算集群的能力助力我们缩短对不同参数模型的训练与评估,从而提供**的参数模型供我们使用,下面我们将一步一步介绍如何使用其提供的该特性。首先我们定义工作流中涉及到的阶段步骤,具体如下所示。
上述完成工作流水线各阶段的任务后,接下来我们就需要指定各阶段的参数列表,从而便于Spark形成不同的组合进行模型训练。
有了以上其实我们就可以单纯的进行模型训练了,但是这样训练除的模型并无法评估出最好的一个模型。我们需要指定一个评估器用来评估实际效果是否符合**。这里我们主要采用了类。
最后我们需要能够自动调整超参数,并自动分配数据集的方式将上述的各部分组成从而形成最终有效的模型。
而具体的使用与之前逻辑回归的方式如出一辙。
如果读者需要将该模型进行持久化可以采用该方式进行实际的持久化,当然读取时需要采用与写入一致的类,否则将无法正确读取。
参考机器学习教程中对应章节的内容可弥补关于各类算法的基础知识,接下来我们将仅从基于Spark的实战角度出发进行列举常用的方式对特定的数据预处理。
下面我们将介绍较通用的三种的针对数据进行处理的方式,其中一种上述的教程已经使用了,这里将仅做为介绍进行概述。
点击此处查看代码示例
其主要参考了基于R语言的formula设计思路,当然其中仅仅支持有限有限的操作符。并且其中对于字符串的处理是采用独热编码(One-hot)的方式,具体的使用方式如下。
支持的操作符如下:
如果读者不了解其中表达式的作用,接下来我们将举一个例子,假设a,b为2个特征,y是应变量。利用上述的公式我们将可以写出如下的语句。
如果读者还是不能理解我们可以通过具体的例子来进行介绍,首先我们准备以下相关数据。
将上面的数据采用公式进行处理后,结果数据将如下所示。
上述我们可以看到针对字符串类型的标签采用了字符串索引的方式进行映射,至此关于介绍到此为止。
将一个向量列中的特征进行索引,一般用于决策树。其对于离散特征的索引是基于0开始的,但是并不保证值每次对应的索引值一致,但是对于0必然是会映射到0。
如果读者希望控制最大的分类数,则可以通过继续控制。
最好理解的分桶方式,即我们认为的将数值的区间限定好,让对应的数据归纳到对应的桶内。对于
无限大与无限小则可以使用与填充。
同时为了处理null或NaN值,必须指定handlerInvalid参数,如果需要保留可以使用keep,报错
则填入null或error,以及skip跳过。
该方式不用用户进行预设,其可以根据百分比进行拆分,读者可以通过设置
近似分位数计算的相对误差。通过设置handleInvalid选择保留还是删除数据集中的NaN值。如果
选择保留NaN值,则将对其进行特殊处理并将其放入自己的存储桶中,如读者设定4个桶,则其会被
放入一个特殊的桶[4]中。
基于StandardScaler将一组特征值归一化成平均值为0而标准偏差为1的一组新值。通过withStd标志设置单位标准差,而withMean标识将使数据在缩放之前进行中心化。稀疏向量中心化非常耗时,因为一般会将它们转化为稠密向量。
将向量中的值基于给定的最小值到最大值按比例缩放。如最小值为0且最大值为1,则所有值将介于0和1之间。
基于MaxAbsScaler将每个值除以该特征的最大绝对值来缩放数据。计算后的值将在-1与1之间。
基于ElementwiseProduct将一个缩放向量对某向量中的每个值以不同的尺度进行缩放。
用幂范数来缩放多维向量,Normalizer的作用范围是每一行。其通过参数P设置几范数,为1表示曼哈顿范数,2表示欧几里德范数等。
最简单的方式就是将对应的类型映射到对应ID形成关系。
基于字符串索引的方式还可以根据索引反推出对应的类型名称。
基于One-hot(独热编码)在类别变量索引之后进行转换。其目的主要是因为经过字符串索引后就存在了一种大小关系,比如对应颜色这种类别是无意义的所以我们需要将其转换为向量中的一个布尔值元素。
在实际的预处理过程中我们往往会遇到需要将文档等由多种词语构成的数据进行分析。而针对这类
文本数据的分析,我们需要借助以下几个流程将这类文本数据转换为具体的特征数据从而便于我们
进行数据的分析处理。
首先我们需要将一段话进行分词,分词是将任意格式的文本转变成一个“符号”列表或者一个单词列表的过程。
不仅可以基于通过空格分词,也可以使用RegexTokenizer指定的正则表达式来分词。
分词后的一个常见任务是过滤停用词,这些常用词在许多分析中没有什么意义,因此应被删除。
字符串分词和过滤停用词之后,会得到可作为特征的一个词集合。
一旦有了词特征,就可以开始对单词和单词组合进行计数,以便在我们的模型中使用可以通过setMinTF来决定词库中是否包含某项,通过setVocabSize设置总的最大单词量。
实际上它是一个稀疏向量,包含总的词汇量、词库中某单词的索引,以及该单词的计数。
另一种将本文转换为数值表示的方法是使用词频-逆文档频率(TF-IDF)。最简单的情况是,TF-IDF度量一个单词在每个文档中出现的频率,并根据该单词出现过的文档数进行加权,结果是在较少文档中出现的单词比在许多文档中出现的单词权重更大。如果读者希望能够更深入的单独了解该技术可以阅读本文章
输出显示总的词汇量、文档中出现的每个单词的哈希值,以及这些单词的权重。
因为机器学习只能接受数值形式,为此需要进行转换,而Word2Vec就是词嵌入的中的一种。而Spark内使用的是基于模型,而该模型主要是根据输入的词语推算出上下文可能与该词组合的其他词语。如果希望学习Word2Vec则可以参考本文档
主成分(PCA)是一种数据方法, 用于找到我们的数据中最重要的成分。PCA使用参数k指定要创建的输出特征的数量,这通常应该比输入向量的尺寸小的多。
多项式扩展基于所有输入列生成交互变量。对于一个二阶多项式,Spark把特征向量中的每个值乘以所有其他值,然后将结果存储成特征。
ChiSqSelector利用统计测试来确定与我们试图预测的标签无关的特征,并删除不相关的特征。其提供了以下集中方法:
- numTopFea tures:基于p-value排序
- percentile:采用输入特征的比例
- fpr:设置截断p-value
逻辑回归是一种线性模型,为输入的每个特征赋以权重之后将他们组合在一起,从而获得该输入属于特定类的概率。
超参数
训练参数
预测参数
决策树是一种更友好和易于理解的分类方法,因为它类似人类经常使用的简单决策模型。
超参数
训练参数
随机森林,我们只训练大量的树,然后平均他们的结果做出预测。利用梯度提升树,每棵树进行加权预测。
随机森林超参数
梯度提升树超参数
朴素贝叶素分类是基于贝叶斯定理的分类方法,通常用于文本或文档分类,所有的输入特征碧玺为非负数。
超参数
训练参数
线性回归假定输入特征的线性组合(每个特征乘以权重的综合)将得到(有一定高斯误差的)输出结果,具体参数同分类中该算法。
线性回归的广义形式使你可以更细粒度地控制使用各种回归模型
超参数
预测参数
用于回归分析的决策树不是在每个叶子节点上输出离散的标签,而是一个连续的数值,但是可解释性和模型结构仍然适用。对应参数可以参考分类中该算法。
随机森林和梯度提升树模型可应用于分类和回归,它们与决策树具有相同的基本概念,不是训练一棵树而是很多树来做回归分析。
用于回归任务的评估器称为 RegressionEvaluator,支持许多常见的回归度量标准。与分类评估器一样,RegressionEvaluator 需要两项输入,一个表示预测值,另一个表示真是标签的值。
主要采用ALS(交替最小二乘法)为每个用户和物品建立k维的特征向量,从而可以通过用户和物品向量的点积来估算该用户
对物品的评分值,所以只需要用户-物品对的评分数据作为输入数据集,其中有三列:用户Id列、物品Id列和评分列。评分
可以是显式的,即我们想要直接预测的数值登记;或隐式的,在这种情况下,每个分数表示用户和物品之间的交互强度,它
衡量用户对该物品的偏好程度。
超参数
训练参数
其中最终主要的就是数据块,通常的做法是每个数据块大概分配一百万到五百万各评分值,如果每个数据块的数据量少于这个数字,则太多的数据块可能会影响性能。
预测参数
主要的参数为冷启动策略,该参数用来设置模型应为未出现过在训练集中的用户或物品推荐什么,可通过coldStartStrategy设置,可以选择drop和nan设置。
针对训练的模型效果我们依然需要针对其进行评估,这里我们可以采用与回归算法中相同的评估器进行评估。
对于度量指标我们通过回归度量指标与排名指标进行度量,首先是回归度量指标,我们可以简单的查看每个用户和项目的实际评级与预测值的接近程度。
k-means算法中,用户在数据集中随机选择数量为k的数据点作为处理聚类的聚类中心,未分配的点基于他们与这些
聚类中心的相似度(欧氏距离)倍分配到离他们最近的聚类中。分配之后,再根据被分配到一个聚类的数据点再计算
聚类的新中心,并重复该过程,直到到达有限的迭代次数或直到收敛。
超参数
训练参数
计算数据点与每个聚类中心点的距离,可以采用ClusterEvaluator评估器
超参数
训练参数
超参数
训练参数
超参数
训练参数
预测参数
点击此处查看代码示例
下面我们将以Spark ML训练模型,并将模型导出为PMML供Java应用进行调用,为此我们需要使用以下几个类库。
- jpmml-sparkml
- jpmml-evaluator
其中需要将数据模型的元数据,以及对应训练好的模型放入构造函数中,借助于工具类将PMML持久化为具体的文件。完成上述的模型写入后,我们就可以在具体需使用的应用中引用依赖,然后基于下述的方式进行读取即可。
上述代码中我们需要通过其提供的方法获取算法模型所需要的入参,根据入参的匹配到实际业务场景中对应的数据,当然这里笔者实际数据名称与模型名称一致,所以直接采用获取到对应的值,通过转换到要求的对象类型。最后将数据填入字典后通过即可使用对应算法模型进行模型调用。当然返回的结果也是字典类型,我们需要根据实际需要从中读取我们感兴趣的值即可。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/12346.html