之前担任数据工程师时,由于不熟悉机器学习的流程,团队分工又很细,沟通不畅,机器学习工程师也没有和我谈论数据质量的问题,对于异常值,我采用的做法只是简单地过滤掉,或者将其置为0,而没有考虑到一些异常值可能会影响模型的准确度。因此作为一名数据工程师,了解机器学习的完整流程,还是很有必要的。
环境准备
集群环境Centos7.6默认的Python版本为2.7,鉴于目前机器学习的Python库已大量迁移至Python3,我们需要先把集群的Python替换掉。我们选用的是Anaconda3,Anaconda包含了conda、Python、ipython notebook在内的超过180个科学包及其依赖项,是比较理想的机器学习开发环境。
1.anaconda安装比较简单,首先去官网或者清华镜像下载安装包,我下载的是 Anaconda3-2020.02-Linux-x86_64.sh
。
2.直接执行 ./Anaconda3-2020.02-Linux-x86_64.sh
,回车输入 yes
,设置安装路径,我们安装在 /opt/cloudera/anaconda3
,
3.如果提示“tar (child): bzip2: Cannot exec: No such file or directory”,需要先安装bzip2,执行命令 yum-y install bzip2
安装即可。
4.安装完后,提示设置anaconda的PATH路径,这里需要设置全局路径,因为要确保pyspark任务提交过来之后可以使用python3,所以输入“no”,重新设置PATH
设置全局的anaconda3的PATH
echo "export PATH=/opt/cloudera/anaconda3/bin:$PATH" >> /etc/profile source /etc/profile
5.验证Python版本
[root@cdh1 anaconda3]# python Python 3.7.6 (default, Jan 8 2020, 19:59:22) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information. >>>
6.在CM配置Spark的Python环境
修改spark-env.sh配置
export PYSPARK_PYTHON=/opt/cloudera/anaconda3/bin/python export PYSPARK_DRIVER_PYTHON=/opt/cloudera/anaconda3/bin/python
修改完成后重启即可。
7.现在我们的PySpark使用的就是python3了.
[root@cdh2 ~]# pyspark Python 3.7.6 (default, Jan 8 2020, 19:59:22) [GCC 7.3.0] :: Anaconda, Inc. on linux Type "help", "copyright", "credits" or "license" for more information. Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). Welcome to ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /__ / .__/\_,_/_/ /_/\_\ version 3.0.0 /_/ Using Python version 3.7.6 (default, Jan 8 2020 19:59:22) SparkSession available as 'spark'.
机器学习介绍
好的,现在我们回到正题,
机器学习是一个运用统计学、线性代数和数值优化从数据中获取模式的过程。机器学习分为监督学习,无监督学习,半监督学习和强化学习。我们主要介绍监督学习和无监督学习。
监督学习
监督学习中数据由一组输入记录组成,每个记录都有关联的标签,目标是预测给定的未标记输入的输出标签。这些输出标签可以是离散的,也可以是连续的,这给我们带来了两种类型的监督机器学习:分类和回归。
在分类问题中,目标是将输入分离为一组离散的类或标签。例如在二分类中,如何识别狗和猫,狗和猫就是两个离散标签。
在回归问题中,要预测的值是连续数,而不是标签。这意味着您可以预测模型在训练期间未看到的值。例如,您可以构建一个模型来预测给定温度的每日冰淇淋销售情况。您的模型可能会预测值 $77.67,即使它所训练的输入/输出对都没有包含该值。
Spark中流行的分类和回归算法
Algorithm | Typical usage |
Linear regression | Regression |
Logistic regression | Classification (we know, it has regression in the name!) |
Decision trees | Both |
Gradient boosted trees | Both |
Random forests | Both |
Naive Bayes | Classification |
Support vector machines (SVMs) | Classification |
无监督学习
获取监督学习所需的标记数据可能非常昂贵或不可行。这就是无监督学习发挥作用的地方。无监督的 ML 无需预测标签,而是帮助您更好地了解数据的结构。例如下图,对于每个数据点(x1、x2),没有已知的真实标签,但是通过将无监督的机器学习应用于我们的数据,我们可以找到自然形成的群集,如右图所示
无监督机器学习可用于异常值检测或作为监督机器学习的预处理步骤,例如,减少数据集的维度(即每个基准的维度数),这对于减少存储要求或简化下游任务非常有用。MLlib 中的一些无人监督的机器学习算法包括 k-means、延迟二次分配 (LDA) 和高斯混合模型。
本文我们将介绍如何创建和调整 ML 管道。在 MLlib 中,管道 API 提供基于 DataFrame 构建的高级别 API,用于组织机器学习工作流。管道 API 由一系列transformers 和estimators组成。
我们使用Airbnb 的开放数据集,它包含有关旧金山 Airbnb 租赁的信息,例如卧室数量、位置、审核分数等,我们的目标是构建一个模型来预测该城市房源的夜间租赁价格。这是一个回归问题,因为价格是一个连续变量。本文将指导您完成数据科学家处理此问题的工作流,包括特征工程、构建模型、超参数调优和评估模型性能。
Spark中ML Pipeline中的几个概念
Transformer
接受 DataFrame 作为输入,并返回一个新的 DataFrame,其中附加了一个或多个列。Transformer不会从数据中学习任何参数,只需应用基于规则的转换,即可为模型训练准备数据或使用训练有素的 MLlib 模型生成预测。它们具有 .transform()
方法。
Estimator
通过 .fitt()
方法从DataFrame中学习(或“拟合”)参数,并返回一个Model,它是一个转换器。
Pipeline
将一系列Transformer和Estimator组织到一个模型中。尽管管道本身Estimator,但是 pipeline.fit()
的输出返回一个PipelineModel,即一个Estimator。
数据提取与探索
我们对示例数据集中的数据进行了稍微的预处理,以去除异常值(例如,Airbnbs发布价为$ 0 /晚),将所有整数都转换为双精度型,并选择了一百多个字段中的信息子集。此外,对于数据列中所有缺失的数值,我们估算了中位数并添加了一个指示符列(列名后跟_na,例如bedrooms_na)。这样,ML模型或人工分析人员就可以将该列中的任何值解释为估算值,而不是真实值。
让我们快速浏览一下数据集和相应的架构(输出仅显示列的子集):
>>> filePath = """/data/sparkdata/sf-airbnb/sf-airbnb-clean.parquet/""" >>> airbnbDF = spark.read.parquet(filePath) >>> airbnbDF.select("neighbourhood_cleansed", "room_type", "bedrooms", "bathrooms", ... "number_of_reviews", "price").show(5) 20/09/01 20:20:09 WARN util.package: Truncated the string representation of a plan since it was too large. This behavior can be adjusted by setting 'spark.sql.debug.maxToStringFields'. +----------------------+---------------+--------+---------+-----------------+-----+ |neighbourhood_cleansed| room_type|bedrooms|bathrooms|number_of_reviews|price| +----------------------+---------------+--------+---------+-----------------+-----+ | Western Addition|Entire home/apt| 1.0| 1.0| 180.0|170.0| | Bernal Heights|Entire home/apt| 2.0| 1.0| 111.0|235.0| | Haight Ashbury| Private room| 1.0| 4.0| 17.0| 65.0| | Haight Ashbury| Private room| 1.0| 4.0| 8.0| 65.0| | Western Addition|Entire home/apt| 2.0| 1.5| 27.0|785.0| +----------------------+---------------+--------+---------+-----------------+-----+ only showing top 5 rows
我们的目标是预测租赁物业的每晚价格。
在数据科学家开始建立模型之前,他们需要探索和理解他们的数据。他们通常会使用Spark对数据进行分组,然后使用数据可视化库(例如matplotlib)来可视化数据。这个探索的过程我们在此忽略。