Spark快速大数据分析——机器学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012848709/article/details/84841909

楔子

《Spark快速大数据分析》学习

11 基于MLlib的机器学习

​ MLlib是Saprk中提供机器学习函数的库。它是专门在集群上并行的情况而设计的。MLlib中包含许多机器学习算法,可以在Spark支持的所有编程语言中使用。

11.1 概述

​ MLlib的设计里面非常简单:把数据已RDD的形式表示,然后在分布式数据集上调用各种算法。MLlib引入了一些数据类型(例如点和向量),不过归根结底,MLlib就是RDD上一系列可供调用的函数的集合。例如,如果使用MLlib来完成文本分类的任务,只需要按如下操作

​ 1 首先用字符串RDD来表示你的消息

​ 2 运行MLlib中的一个特征提取算法把文本数据转换为数值特征;该操作返回一个向量RDD。

​ 3 对向量RDD调用分类算法;这步会返回一个模型对象,可以使用该对象对新的数据点进行分类。

​ 4 使用MLlib的评估函数在测试数据集上评估模型

​ 需要注意的是,MLlib中只包含能够运行在集群上运行良好的并行算法,这一点很重要。有些景点的机器学习算法并没有包含在其中,就是因为他们不能被并行执行。相反地,一些较新的研究得出的算法因为使用与集群,也被包含在MLlib中,例如分布式随机森林算法等。这样的选择使得MLlib中的每一个算法都适用于大规模数据集。如果你要在许多小规模数据集生训练各种机器学习模型,最好还是在各节点上使用单节点的机器学习算法库实现。比如可以使用Spark的Map操作在各节点生并行使用。类似地,我们在机器学习流水线中也常常用同一算法的不同参数对小规模数据集分别训练,来选出最好的一组参数。在 Spark 中,你可以通过把参数列表传给 parallelize() 来在不同的节点上分别运行不同的参数,而在每个节点上则使用单节点的机器学习库来实现。只有当你需要在一个大规模分布式数据集上训练模型时,MLlib 的优势才能突显出来。

11.2 系统要求

​ 首先,你需要为操作系统安装 gfortran 运行库。如果 MLlib 警告找不到 gfortran 库的话,可以按 MLlib 网站(http://spark.apache.org/docs/latest/mllib-guide.html)上说明的步骤处理。其次,如果你要在 Python 中使用 MLlib,你需要安装 NumPy(http://www.numpy.org/)。如果你的 Python 没有安装 NumPy(即你无法使用 import numpy ),最简单的办法就是使用 Linux 的包管理工具来安装 python-numpy包或 numpy 包,或者使用第三方定制的 Python 版本,比如 Anaconda(http://continuum.io/downloads)。

11.3 机器学习基础

​ 机器学习算法尝试根据训练数据(training data)使得表示算法行为的数学目标最大化,并以此来进行预测或作出决定。机器学习问题分为几种,包括分类、回归、聚类,每种都有不一样的目标。拿分类(classification)作为一个简单的例子:分类是基于已经被标记的其他数据点(比如一些已经分别被标记为垃圾邮件或非垃圾邮件的邮件)作为例子来识别一个数据点属于几个类别中的哪一种(比如判断一封邮件是不是垃圾邮件)。

​ 所有的学习算法都需要定义每个数据点的特征(feature)集,也就是传给学习函数的值。举个例子,对于一封邮件来说,一些特征可能包括其来源服务器、提到 free 这个单词的次数、字体颜色等。在很多情况下,正确地定义特征才是机器学习中最有挑战性的部分。例如,在产品推荐的任务中,仅仅加上一个额外的特征(例如我们意识到推荐给用户的书籍可能也取决于用户看过的电影),就有可能极大地改进结果

​ 大多数算法都只是专为数值特征(具体来说,就是一个代表各个特征值的数字向量)定义的,因此提取特征并转化为特征向量是机器学习过程中很重要的一步。例如,在文本分类中(比如垃圾邮件和非垃圾邮件的例子),有好几个提取文本特征的方法,比如对各个单词出现的频率进行计数。

11.4 数据类型

​ MLlib包含一些特有的数据类型,他们位于org.apache.spark.mlib或pyspark.mlib内。

  • Vector

    一个数学向量。MLlib既支持稠密向量也支持稀疏向量,前者表示向量的每一位都存储下来,后者则只存储非零为以节约空间。向量可以通过mlib.linalg.Vectors类创建出来。

  • LabeledPoint

    在诸如分类和回归这样的监督式学习算法中,LabeledPoint用来表示带标签的数据点。它包含一个特征向量与一个标签(由一个浮点数表示),位置在mlib.regression包中

  • Rating

    用户对一个产品的评分,在mlib.recommendation包中,用户产品推介

  • 各种Model类

    每个Model都是训练算法的结果,一般有一个predict()方法可以用来对新的数据点或数据点组成的RDD应用模型进行预测

​ 大多数算法直接操作由 Vector 、 LabeledPoint 或 Rating 对象组成的 RDD。你可以用任意方式创建出这些对象,不过一般来说你需要通过对外部数据进行转化操作来构建出RDD——例如,通过读取一个文本文件或者运行一条 Spark SQL 命令。接下来,使用map() 将你的数据对象转为 MLlib 的数据类型。

操作向量


​ 作为MLlib最常用的数据类型,Vector类有一些需要注意的地方。

​ 第一,向量有2种:稠密向量和稀疏向量。稠密向量把所有维度的值存放在一个浮点型数数组中。例如,一个100维的向量会存储100个双精度浮点数。相比之下,稀疏向量只把个维度中非0字存储下来。当最多只有 10% 的元素为非零元素时,我们通常更倾向于使用稀疏向量(不仅是出于对内存使用的考虑,也是出于对速度的考虑)。许多特征提取技术都会生成非常稀疏的向量,所以这种方式常常是一种很关键的优化手段。

​ 第二,创建向量的方式在各种语言中有一些细微的差别。 而在 Java 和 Scala 中,都需要使用 mllib.linalg.
Vectors 类。

//创建稠密向量<1.0,2.0,3.0>;
Vector dense = Vectors.dense(1.0,2.0,3.0);
//
Vector dense2 = Vectors.dense(new double[]{1.0,2.0,3.0});

//创建稀疏向量<1.0,0.0,2.0,0.0>
Vector sparse = Vectors.sparse(4, new int[]{0,2},new double[]{1.0,2.0});

11.5 算法

11.5.1 特征提取

mlib.feature包中包含一些用来进行常见特征转化的类。这些类中从文本(或其他表示)创建特征向量的算法,也对特征向量正规化和伸缩变换的方法。

TF-IDF

​ 词频——逆文档频率是一种用来从文本文档中生成特征向量的简单方法。它为文档中的每个词计算两个统计值:一个是词频(TF),也就是每个词在文档中出现的次数,另一个逆文档频率(IDF),用来衡量一个词在整个文档语料库中出现的(逆)频繁程度。这些值得积,也就是TF*IDF,展示了一个词与特定文档的相关程序(比如这个词在某文档中很常见,但在整个语料库中却很少见)。

​ MLlib有两个算法可以用来计算TF-IDF: HashingTF 和 IDF ,都在 mllib.feature 包内。HashingTF 从一个文档中计算出给定大小的词频向量。为了将词与向量顺序对应起来,它使用了哈希法(hasing trick)。在类似英语这样的语言中,有几十万个单词,因此将每个单词映射到向量中的一个独立的维度上需要付出很大代价。而 HashingTF 使用每个单词对所需向量的长度 S 取模得出的哈希值,把所有单词映射到一个 0 到 S-1 之间的数字上。由此我们可以保证生成一个 S 维的向量。在实践中,即使有多个单词被映射到同一个哈希值上,算法依然适用。MLlib 开发者推荐将 S 设置在 2^18到 2^20 之间。

11.5.2 统计

​ 不论是在即时的探索中,还是在机器学习的数据理解中,基本的统计都是数据分析的重要部分。MLlib 通过 mllib.stat.Statistics 类中的方法提供了几种广泛使用的统计函数,这些函数可以直接在 RDD 上使用。一些常用的函数如下所列。

  • Statistics.colStats( rdd )

    计算由向量组成的 RDD 的统计性综述,保存着向量集合中每列的最小值、最大值、平均值和方差。这可以用来在一次执行中获取丰富的统计信息。

  • Statistics.corr( rdd, method )

    计算由向量组成的 RDD 中的列间的相关矩阵,使用皮尔森相关(Pearson correlation)或斯皮尔曼相关(Spearman correlation)中的一种(method 必须是 pearson 或 spearman
    中的一个)。

  • Statistics.corr( rdd1, rdd2, method )

    计算由 LabeledPoint 对象组成的 RDD 中每个特征与标签的皮尔森独立性测试(Pearson’s independence test) 结 果。 返 回 一 个 ChiSqTestResult 对 象, 其 中 有 p 值(p-value)、测试统计及每个特征的自由度。标签和特征值必须是分类的(即离散值)。

11.5.3 分类和回归

​ 分类与回归是监督式学习的两种主要形式。监督式学习指算法尝试使用有标签的训练数据(也就是已知结果的数据点)根据对象的特征预测结果。分类和回归的区别在于预测的变量的类型:在分类中,预测出的变量是离散的(也就是一个在有限集中的值,叫作类别);比如,分类可能是将邮件分为垃圾邮件和非垃圾邮件,也有可能是文本所使用的语言。在回归中,预测出的变量是连续的(例如根据年龄和体重预测一个人的身高)。

​ 分类和回归都会使用 MLlib 中的 LabeledPoint 类。这个类在 mllib.
regression 包中。一个 LabeledPoint 其实就是由一个 label ( label 总是一个 Double 值,不过可以为分类算法设为离散整数)和一个 features 向量组成。

​ MLlib 包含多种分类与回归的算法,其中包括简单的线性算法以及决策树和森林算法。

  1. 线性回归

    线性回归是常用的方法之一,是指用特征的线性组合来预测输出值。MLlib 也支持 L1和 L2的正则的回归,通常称为 Lasso 和 ridge 回归。

    线性回归算法可以使用的类包括 mllib.regression.LinearRegressionWithSGD 、 LassoWithSGD以及 RidgeRegressionWithSGD 。这遵循了 MLlib 中常用的命名模式,即对于涉及多个算法的问题,在类名中使用“With”来表明所使用的算法。这里,SGD 代表的是随机梯度下降法。

    这些类都有几个可以用来对算法进行调优的参数

    • numIterations 要运行的迭代次数(默认值: 100 )
    • stepSize
      梯度下降的步长(默认值: 1.0 )。
    • • intercept
      是否给数据加上一个干扰特征或者偏差特征——也就是一个值始终为 1 的特征(默认值: false )。
    • regParam
      Lasso 和 ridge 的正规化参数(默认值: 1.0 )。

    调用算法的方式在不同语言中略有不同。在Java和Scala中,你需要创建一个LinearRegressionWithSGD对象,调用它的setter方法来设置参数,然后调用run()来训练模型。在Python中,你需要使用类的方法LinearRegressionWithSGD.train(),并对其传递键值对参数。在这两种情况中,你都需要传递一个由LabeledPoint组成的RDD,

  2. 逻辑回归

    逻辑回归是一种二元分类方法,用来寻找一个分隔阴性和阳性示例的线性分割平面。在 MLlib 中,它接收一组标签为 0 或 1 的 LabeledPoint ,返回可以预测新点的分类的LogisticRegressionModel 对象。

  3. 支持向量机

    支持向量机(简称 SVM)算法是另一种使用线性分割平面的二元分类算法,同样只预期 0 或者 1 的标签。通过 SVMWithSGD 类,我们可以访问这种算法,它的参数与线性回归和逻辑回归的参数差不多。返回的 SVMModel 与 LogisticRegressionModel 一样使用阈值的方式进行预测。

  4. 朴素贝叶斯

    朴素贝叶斯(Naive Bayes)算法是一种多元分类算法,它使用基于特征的线性函数计算将一个点分到各类中的得分。这种算法通常用于使用 TF-IDF 特征的文本分类,以及其他一些应用。MLlib 实现了多项朴素贝叶斯算法,需要非负的频次(比如词频)作为输入特征。

    在 MLlib 中,你可以通过 mllib.classification.NaiveBayes 类来使用朴素贝叶斯算法。它支持一个参数 lambda (Python 中是 lambda_ ),用来进行平滑化。你可以对一个由 LabeledPoint组成的 RDD 调用朴素贝叶斯算法,对于 C 个分类,标签值范围在 0 至 C-1 之间

15.5 协同过滤推荐

​ 协同过滤是一种根据用户对各种产品的交互与评分来推荐新产品的推荐系统技术。协同过滤吸引人的地方就在于它只需要输入一系列用户 / 产品的交互记录:无论是“显式”的交互(例如在购物网站上进行评分)还是“隐式”的(例如用户访问了一个产品的页面但是没有对产品评分)交互皆可。仅仅根据这些交互,协同过滤算法就能够知道哪些产品之间比较相似(因为相同的用户与它们发生了交互)以及哪些用户之间比较相似,然后就可以作出新的推荐。

​ 尽管 MLlib 的 API 使用了“用户”和“产品”的概念,但你也可以将协同过滤用于其他应用场景中,比如在社交网络中推荐用户,为文章推荐要添加的标签,为电台推荐歌曲等。

交替最小二乘

​ MLlib 中包含交替最小二乘(简称 ALS)的一个实现,这是一个协同过滤的常用算法,可以很好地扩展到集群上。 它位于 mllib.recommendation.ALS 类中

ALS 会为每个用户和产品都设一个特征向量,这样用户向量与产品向量的点积就接近于他们的得分。它接收下面所列这些参数。

  • rank
    使用的特征向量的大小;更大的特征向量会产生更好的模型,但是也需要花费更大的计算代价(默认值: 10 )。
  • iterations
    要执行的迭代次数(默认值: 10 )。
  • lambda
    正则化参数(默认值: 0.01 )。
  • alpha
    用来在隐式 ALS 中计算置信度的常量(默认值: 1.0 )。
  • numUserBlocks , numProductBlocks
    切分用户和产品数据的块的数目,用来控制并行度;你可以传递
    -1来让 MLlib 自动决定(默认行为)

​ 要使用ALS算法,你需要有一个由 mllib.recommendation.Rating 对象组成的 RDD,其中包含一个用户ID,一个产品ID,一个评分。实现过程中的一个挑战是每个ID都需要时一个32的整形值,如果ID是字符串或者更大的数字,推荐在ALS中使用ID的哈希值。还有一种办法是broadcast() 一张从产品 ID 到整型值的表,来赋给每个产品独特的 ID

​ ALS 返回一个 MatrixFactorizationModel 对象来表示结果,可以调用 predict() 来对一个由(userID, productID) 对组成的 RDD 进行预测评分。 8 你也可以使用 model.recommendProducts(userId, numProducts) 来为一个给定用户找到最值得推荐的前 numProduct 个产品。注意,和 MLlib 中的其他模型不同, MatrixFactorizationModel 对象很大,为每个用户和产品都存储了一个向量。这样我们就不能把它存到磁盘上,然后在另一个程序中读取回来。不过,你可以把模型中生成的特征向量 RDD,也就是 model.userFeatures 和 model.productFeatures 保存到分布式文件系统上。

猜你喜欢

转载自blog.csdn.net/u012848709/article/details/84841909