Spark:机器学习模块 ML MLlib

前言

    从Spark 1.2开始,spark机器学习库包分为两个:MLlib和ML。MLlib包是基于RDD(弹性分布式数据集),ML包是基于DataFrame。RDDDataFrame更“低级”,因为它们向最终用户揭示了物理执行特征(比如分区),基于DataFrame的API更加的用户友好、简洁。从Spark2.0开始,基于RDD的API进入维护模式(即不增加任何新的特性),并预期于3.0版本的时候被移除出MLLib。因此建议学习机器学习时使用ML包。

df = spark.createDataFrame([(0, "a"),(1, "b"),(2, "c"),(3, "a"),(4, "a"),(5, "c")], ["id", "category"])

 

基础

    Spark机器学习的流程和传统的机器学习流程一样,即:数据处理—建模—模型评估

  数据处理

  • 数据处理:特征类型通常有数值特征、类别特征、文本特征等。数值特征可直接作为特征向量的维度使用;类别特征通常会进行编号,将其转化为数值特征;文本特征需要进行分词、去停用词、词稀疏编码(如StringIndexer)等处理。数据处理有时还需要特征归一化正则化二值化等。最终通常将各变量划分为两部分:由各自变量组成的特征向量(features)和被视为因变量的目标变量(label)。

 

  建模

  • 建模:目前spark机器学习库里包含了常见的传统机器学习的算法(分类、回归、聚类、降维、协同推荐、异常检测、降维等),如分类算法有线性支持向量机(LinearSVM)、逻辑回归、决策树、梯度提升树、随机森林、朴素贝叶斯、多元感知机、一对多分类器等。更多请查看官方文档Spark官方文档(python版)

 

  • 参数设置:参数设置通常有两种方式,一种是在创建模型时对各所需参数进行设置;另一种是使用网格搜索,一次性传入多个参数值通过模型评估得到其中最佳的参数值建立模型。通过网格搜索的方法通常要与交叉验证(CrossValidator)和训练-验证切分(TrainValidationSplit)结合使用。

 

  模型评估

  • 评估器:二元分类为BinaryClassificationEvaluator();多元分类为MulticlassClassificationEvaluator();回归问题为RegressionEvaluator();聚类问题为ClusteringEvaluator()…

 

  • 评估指标:回归问题可用MSE、RMSE、MAE、R2等,二元分类问题可用ROC、AUC等;多元分类问题可用f1、Precision、Recall、accuracy等…

 

  • 在Spark的ml中实现了三种impurity的度量方法:信息熵Entropy、基尼系数Gini、方差Variance。其中Entropy和Gini用来处理离散值,即处理分类问题,而Variance用来处理连续值,即回归

 

Pipeline

  • Spark ML API引入了pipeline概念,该概念主要受scikit-learn项目的启发。
  • Transformer:翻译成转换器,是一种可以将一个DataFrame转换为另一个DataFrame的算法。
  • Estimator:翻译成估计器或评估器,它是学习算法或在训练数据上的训练方法的概念抽象。在 Pipeline 里通常是被用来操作 DataFrame 数据并生产一个 Transformer。
  • PipeLine:翻译为工作流或者管道。工作流将多个工作流阶段(转换器和估计器)连接在一起,形成机器学习的工作流,并获得结果输出。
  • 要构建一个 Pipeline工作流,首先需要定义 Pipeline 中的各个工作流阶段PipelineStage(即转换器和评估器)
    # 各特征组成一个特征向量(属于Transformer
    assembler = VectorAssembler().setInputCols(featuresArray).setOutputCol("features")
    # 建立一个朴素贝叶斯模型(属于Estimator
    nb = NaiveBayes().setLabelCol("label").setFeaturesCol("features")
    # 创建管道(将Transformer和Estimator连接在一起
    pipeline = Pipeline().setStages([assembler,nb])

     

示例

''' 
内容:pyspark实现逻辑回归二元分类
版本:spark 2.4.4
数据:垃圾邮件数据
数据源:http://archive.ics.uci.edu/ml/datasets/Spambase
'''

from pyspark.sql import SparkSession
from pyspark.sql.functions import col
from pyspark.sql import functions
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import BinaryClassificationEvaluator,MulticlassClassificationEvaluator
from pyspark.ml import Pipeline
from pyspark.ml.tuning import ParamGridBuilder,CrossValidator

spark = SparkSession.builder.master("local").appName("LogisticRegression").getOrCreate()

data = spark.read.format("csv").option("header",True).load(u"D:\Data\spambase.csv")


for i in data.columns:
    data = data.withColumn(i, col(i).cast("Double")) # 将列类型转为数值类型
    if i == "spam":
        data = data.withColumnRenamed(i, "label") # 更改列名

trainingData, testData = data.randomSplit([0.8, 0.2])

featuresArray = data.columns[:-1]

assembler = VectorAssembler().setInputCols(featuresArray).setOutputCol("features")

# 创建逻辑回归模型
lr = LogisticRegression().setLabelCol("label").setFeaturesCol("features")

# 逻辑回归的流水线
lrPipeline = Pipeline().setStages([assembler,lr])

ParamGrid = ParamGridBuilder().addGrid(lr.maxIter,[8, 12, 15,18]).addGrid(lr.regParam,[0.001,0.005]).build()

# 二元分类评估
evaluator = BinaryClassificationEvaluator().setMetricName("areaUnderROC").setRawPredictionCol("rawPrediction").setLabelCol("label")

CV = CrossValidator().setEstimator(lrPipeline).setEvaluator(evaluator).setEstimatorParamMaps(ParamGrid).setNumFolds(3)

# 训练逻辑回归模型
model = CV.fit(trainingData)

# 预测逻辑回归的值
predictions = model.transform(testData)

''' 评估模型指标之AUC '''
AUC = evaluator.evaluate(predictions)

print("The Area Under ROC of LogisticRegression:",AUC)

''' 评估模型指标之ACC '''
evaluatorX = MulticlassClassificationEvaluator().setMetricName("accuracy").setLabelCol("label")

ACC=evaluatorX.evaluate(predictions)

print("The Accuracy of LogisticRegression:",ACC)

 

你可能感兴趣的:(Spark)