【Spark MLlib】(一)架构解析(包含分类、回归、聚类和协同过滤)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析DNS,个人版 1个月
简介: 【Spark MLlib】(一)架构解析(包含分类、回归、聚类和协同过滤)

文章目录


一、前言

二、MLlib的底层基础解析

三、MLlib的算法库分析

四、MLlib的实用程序分析


一、前言


从以下架构图可以看出MLlib主要包含三个部分:


底层基础:包括Spark的运行库、矩阵库和向量库;

算法库:包含广义线性模型、推荐系统、聚类、决策树和评估的算法;

实用程序:包括测试数据的生成、外部数据的读入等功能。


20200401133024392.png


二、MLlib的底层基础解析


底层基础部分主要包括向量接口和矩阵接口,这两种接口都会使用Scala语言基于Netlib和BLAS/LAPACK开发的线性代数库Breeze。


MLlib支持本地的密集向量和稀疏向量,并且支持标量向量。


MLlib同时支持本地矩阵和分布式矩阵,支持的分布式矩阵分为RowMatrix、IndexedRowMatrix、CoordinateMatrix等。


关于密集型和稀疏型的向量Vector的示例如下所示。


20200401133730721.png


2020040113513093.png


疏矩阵在含有大量非零元素的向量Vector计算中会节省大量的空间并大幅度提高计算速度,如下图所示。


20200401135158162.png


标量LabledPoint在实际中也被大量使用,例如判断邮件是否为垃圾邮件时就可以使用类似于以下的代码:


20200401135217477.png


可以把表示为1.0的判断为正常邮件,而表示为0.0则作为垃圾邮件来看待。


对于矩阵Matrix而言,本地模式的矩阵如下所示。


20200401135537747.png


分布式矩阵如下所示:


20200401135522529.png


RowMatrix直接通过RDD[Vector]来定义并可以用来统计平均数、方差、协同方差等:


20200401135634843.png


20200401135639891.png


而IndexedRowMatrix是带有索引的Matrix,但其可以通过toRowMatrix方法来转换为RowMatrix,从而利用其统计功能,代码示例如下所示。


20200401135809765.png


CoordinateMatrix常用于稀疏性比较高的计算中,是由RDD[MatrixEntry]来构建的,MatrixEntry是一个Tuple类型的元素,其中包含行、列和元素值,代码示例如下所示:


20200401135832611.png


三、MLlib的算法库分析


下图是MLlib算法库的核心内容。


20200401140248412.png


在这里我们分析一些Spark中常用的算法:


1) 分类算法


分类算法属于监督式学习,使用类标签已知的样本建立一个分类函数或分类模型,应用分类模型,能把数据库中的类标签未知的数据进行归类。分类在数据挖掘中是一项重要的任务,目前在商业上应用最多,常见的典型应用场景有流失预测、精确营销、客户获取、个性偏好等。MLlib 目前支持分类算法有:逻辑回归、支持向量机、朴素贝叶斯和决策树。


案例:导入训练数据集,然后在训练集上执行训练算法,最后在所得模型上进行预测并计算训练误差。

import org.apache.spark.SparkContext
import org.apache.spark.mllib.classification.SVMWithSGD
import org.apache.spark.mllib.regression.LabeledPoint
// 加载和解析数据文件
val data = sc.textFile("mllib/data/sample_svm_data.txt")
val parsedData = data.map { line =>
  val parts = line.split(' ')
  LabeledPoint(parts(0).toDouble, parts.tail.map(x => x.toDouble).toArray)
}
// 设置迭代次数并进行进行训练
val numIterations = 20
val model = SVMWithSGD.train(parsedData, numIterations)
// 统计分类错误的样本比例
val labelAndPreds = parsedData.map { point =>
val prediction = model.predict(point.features)
(point.label, prediction)
}
val trainErr = labelAndPreds.filter(r => r._1 != r._2).count.toDouble / parsedData.count
println("Training Error = " + trainErr)


2) 回归算法


回归算法属于监督式学习,每个个体都有一个与之相关联的实数标签,并且我们希望在给出用于表示这些实体的数值特征后,所预测出的标签值可以尽可能接近实际值。MLlib 目前支持回归算法有:线性回归、岭回归、Lasso和决策树。


案例:导入训练数据集,将其解析为带标签点的RDD,使用 LinearRegressionWithSGD 算法建立一个简单的线性模型来预测标签的值,最后计算均方差来评估预测值与实际值的吻合度。

import org.apache.spark.mllib.regression.LinearRegressionWithSGD
import org.apache.spark.mllib.regression.LabeledPoint
// 加载和解析数据文件
val data = sc.textFile("mllib/data/ridge-data/lpsa.data")
val parsedData = data.map { line =>
  val parts = line.split(',')
  LabeledPoint(parts(0).toDouble, parts(1).split(' ').map(x => x.toDouble).toArray)
}
//设置迭代次数并进行训练
val numIterations = 20
val model = LinearRegressionWithSGD.train(parsedData, numIterations)
// 统计回归错误的样本比例
val valuesAndPreds = parsedData.map { point =>
val prediction = model.predict(point.features)
(point.label, prediction)
}
val MSE = valuesAndPreds.map{ case(v, p) => math.pow((v - p), 2)}.reduce(_ + _)/valuesAndPreds.count
println("training Mean Squared Error = " + MSE)


3) 聚类算法


聚类算法属于非监督式学习,通常被用于探索性的分析,是根据“物以类聚”的原理,将本身没有类别的样本聚集成不同的组,这样的一组数据对象的集合叫做簇,并且对每一个这样的簇进行描述的过程。它的目的是使得属于同一簇的样本之间应该彼此相似,而不同簇的样本应该足够不相似,常见的典型应用场景有客户细分、客户研究、市场细分、价值评估。MLlib 目前支持广泛使用的K-Mmeans聚类算法。


案例:导入训练数据集,使用 K-Means 对象来将数据聚类到两个类簇当中,所需的类簇个数会被传递到算法中,然后计算集内均方差总和(WSSSE),可以通过增加类簇的个数 k 来减小误差。 实际上,最优的类簇数通常是 1,因为这一点通常是WSSSE图中的 “低谷点”。

import org.apache.spark.mllib.clustering.KMeans
// 加载和解析数据文件
val data = sc.textFile("kmeans_data.txt")
val parsedData = data.map( _.split(' ').map(_.toDouble))
// 设置迭代次数、类簇的个数
val numIterations = 20
val numClusters = 2
// 进行训练
val clusters = KMeans.train(parsedData, numClusters, numIterations)
// 统计聚类错误的样本比例
val WSSSE = clusters.computeCost(parsedData)
println("Within Set Sum of Squared Errors = " + WSSSE)


4) 协同过滤


协同过滤常被应用于推荐系统,这些技术旨在补充用户-商品关联矩阵中所缺失的部分。MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐语义因子进行表达,并且这些因子也用于预测缺失的元素。


案例:导入训练数据集,数据每一行由一个用户、一个商品和相应的评分组成。假设评分是显性的,使用默认的ALS.train()方法,通过计算预测出的评分的均方差来评估这个推荐模型。

import org.apache.spark.mllib.recommendation.ALS
import org.apache.spark.mllib.recommendation.Rating
// 加载和解析数据文件
val data = sc.textFile("mllib/data/als/test.data")
val ratings = data.map(_.split(',') match {
case Array(user, item, rate) => Rating(user.toInt, item.toInt, rate.toDouble)
})
// 设置迭代次数
val numIterations = 20
val model = ALS.train(ratings, 1, 20, 0.01)
// 对推荐模型进行评分
val usersProducts = ratings.map{ case Rating(user, product, rate) => (user, product)}
val predictions = model.predict(usersProducts).map{
case Rating(user, product, rate) => ((user, product), rate)
}
val ratesAndPreds = ratings.map{
case Rating(user, product, rate) => ((user, product), rate)
}.join(predictions)
val MSE = ratesAndPreds.map{
case ((user, product), (r1, r2)) => math.pow((r1- r2), 2)
}.reduce(_ + _)/ratesAndPreds.count
println("Mean Squared Error = " + MSE)


四、MLlib的实用程序分析


实用程序部分包括数据的验证器、Label的二元和多元的分析器、多种数据生成器、数据加载器。


2020040114103469.png

目录
相关文章
|
1月前
|
运维 Kubernetes 监控
深入解析微服务架构的演进与实践
本文旨在探究微服务架构从诞生到成熟的发展历程,分析其背后的技术推动力和业务需求,并结合具体案例,揭示实施微服务过程中的挑战与解决策略。通过对微服务架构与传统单体架构的对比,阐明微服务如何优化现代应用开发流程,提高系统的可扩展性、可维护性和敏捷性。
69 0
|
2天前
|
弹性计算 监控 数据挖掘
事件驱动架构的优势与应用:深度解析与实战应用
【8月更文挑战第17天】事件驱动架构以其松耦合、可扩展性、异步处理、实时性和高可靠性等优势,在实时数据处理、复杂业务流程、弹性伸缩和实时通信等多个领域展现出巨大的应用潜力。通过合理应用事件驱动架构,可以构建灵活、可扩展和可维护的系统架构,满足不断变化的业务需求和技术挑战。对于开发者而言,深入理解事件驱动架构的核心概念和优势,将有助于更好地设计和实现高质量的软件系统。
|
25天前
|
监控 安全 数据安全/隐私保护
ERP系统中的组织架构与权限管理解析
【7月更文挑战第25天】 ERP系统中的组织架构与权限管理解析
66 2
|
1月前
|
监控 负载均衡 安全
微服务架构下的服务发现与注册:技术深度解析
【7月更文挑战第20天】服务发现与注册是微服务架构中不可或缺的一部分,它确保了服务间的动态发现和通信。通过选择合适的实现工具和遵循最佳实践,可以构建出高效、可靠、可扩展的微服务系统。随着技术的不断进步,未来我们还将看到更多创新的服务发现与注册解决方案的出现。
|
1月前
|
监控 Kubernetes 安全
Istio整体架构解析
【7月更文挑战第17天】Istio整体架构分为数据平面(Data Plane)和控制平面(Control Plane)两部分
|
12天前
|
域名解析 网络协议 安全
浅析DNS服务器:办公网DNS的架构思路分享
浅析DNS服务器:办公网DNS的架构思路分享
27 0
|
1月前
|
负载均衡 监控 安全
微服务架构中的API网关模式解析
【7月更文挑战第4天】在微服务架构中,API网关不仅是一个技术组件,它是连接客户端与微服务之间的桥梁,负责请求的路由、负载均衡、认证、限流等关键功能。本文将深入探讨API网关的设计原则、实现方式及其在微服务架构中的作用和挑战,帮助读者理解如何构建高效、可靠的API网关。
|
1月前
|
运维 负载均衡 前端开发
深度解析:Python Web前后端分离架构中WebSocket的选型与实现策略
【7月更文挑战第16天】Python Web开发中,前后端分离常见于实时通信场景,WebSocket作为全双工协议,常用于此类应用。选型时考虑性能、功能、易用性、社区支持和成本。Flask-SocketIO是实现WebSocket的一个选项,它简化了与Flask的集成。案例展示了如何用Flask-SocketIO创建一个实时聊天室:后端处理消息广播,前端通过Socket.IO库连接并显示消息。此实现策略演示了在Python中实现实时通信的基本步骤。
49 0
|
3月前
|
机器学习/深度学习 分布式计算 算法
Spark中的机器学习库MLlib是什么?请解释其作用和常用算法。
Spark中的机器学习库MLlib是什么?请解释其作用和常用算法。
79 0
|
11月前
|
分布式计算 算法 大数据
大数据Spark MLlib推荐算法
大数据Spark MLlib推荐算法
213 0

推荐镜像

更多