Pyspark:V3.2.1
本篇博客主要介绍pyspark.ml.Evaluation包的使用。
1 概览
pyspark.ml.Evaluation包中的评估类主要包括以下几种如下表。
类 | 作用 |
---|---|
Evaluator | 评估器的基类。但是这个类中的_evaluate方法并没有具体实现,其他所有的评估类都继承自该类的子类JavaEvaluator。 |
BinaryClassificationEvaluator | 二分类模型评估器 |
RegressionEvaluator | 回归模型的评估器 |
MulticlassClassificationEvaluator | 多分类模型评估器 |
MultilabelClassificationEvaluator | 多标签分类模型评估器 |
ClusteringEvaluator | 聚类模型评估器 |
RankingEvaluator | 排序学习评估器 |
2 使用案例
这一部分主要是为了展示如何对不同类型的模型的性能进行评估,不会把精力放在模型的训练上。这里使用sklearn.datasets来生成模型训练需要的数据。
2.1 分类模型评估器
2.1.1 二分类
这里先介绍BinaryClassificationEvaluator类中的参数,主要参数如下:
参数 | 作用 |
---|---|
rawPredictionCol | 指定保存raw Prediction的列名。 |
labelCol | 指定保存真实label值的列名。 |
metricName | 指定评估指标。该模型可接受的评估指标值为:areaUnderROC(默认值)、areaUnderPR |
weightCol | 指定各个样例的权重的列名。不是必须的 |
numBins | 分箱数。ROC曲线、PR曲线计算时会 |
举例如下:
import os
from pyspark.sql import SparkSession
from pyspark.ml.classification import *
from sklearn.datasets import *
from pyspark.ml.evaluation import *
from pyspark.ml.linalg import Vectors
os.environ['SPARK_HOME'] ='/Users/sherry/documents/spark/spark-3.2.1-bin-hadoop3.2'
spark=SparkSession.builder.appName('ml').getOrCreate()
#构建二分类数据集
X,y=make_classification(n_samples=500,n_features=5,n_redundant=1,
n_informative=4,n_classes=2)
data_2C=[[Vectors.dense(x_item),int(y_item)] for x_item,y_item in zip(X,y)]
#构建DataFrame
data_2C=spark.createDataFrame(data_2C,['features','label'])
#训练模型
LR=LogisticRegression(featuresCol='features',labelCol='label',
predictionCol='prediction')
LR_model_2C=LR.fit(data_2C)
data_2C=LR_model_2C.transform(data_2C)
#模型评估
#BinaryClassificationEvaluator各个参数都有默认值,所以这里都使用默认值
evaluator=BinaryClassificationEvaluator()
roc=evaluator.evaluate(data_2C)
print(roc) #0.87
2.1.2 多分类
MulticlassClassificationEvaluator类中的参数与BinaryClassificationEvaluator类中的大体相同,但没有numBins参数,另外其新增的参数主要包括以下几种:
参数 | 作用 |
---|---|
metricLabel | 指定参数如下指标计算中的类别:truePositiveRateByLabe、falsePositiveRateByLabel、precisionByLabel、recallByLabel、fMeasureByLabel。指定的类别值必须大于等于0。 |
beta | 指定指标weightedFMeasure、fMeasureByLabel计算时的 β \beta β值。该值可以接收大于0的值作为参数,默认值为1。 |
probabilityCol | 指定预测类的条件概率的列名 |
eps |
另外,metricName参数可接受的评估指标主要有:f1、accuracy、weightedPrecision、weightedRecall、weightedTruePositiveRate、weightedFalsePositiveRate、weightedFMeasure、truePositiveRateByLabel、falsePositiveRateByLabel、precisionByLabel、recallByLabel、fMeasureByLabel、logLoss、hammingLoss
举例如下:
#构造三分类数据
X,y=make_classification(n_samples=500,n_features=4,n_classes=3,n_informative=4,n_redundant=0)
data_2C=[[Vectors.dense(x_item),int(y_item)] for x_item,y_item in zip(X,y)]
#构建DataFrame
data_2C=spark.createDataFrame(data_2C,['features','label'])
#训练模型
LR=LogisticRegression(featuresCol='features',labelCol='label',
predictionCol='prediction')
LR_model_2C=LR.fit(data_2C)
data_2C=LR_model_2C.transform(data_2C)
#模型评估
evaluator=MulticlassClassificationEvaluator(metricLabel=1,
metricName='truePositiveRateByLabel')
tpr_label=evaluator.evaluate(data_2C)
print(tpr_label) #0.721
2.1.3 多标签分类
关于多标签分类可以参考博客:https://blog.csdn.net/yeshang_lady/article/details/128837245。MultilabelClassificationEvaluator类目前还处在实验阶段(ml.Classification中都还没有能够进行标签分类训练的类),现阶段只能对多标签分类的结果进行评估。
该类中metricName参数可接受的评估指标有:subsetAccuracy、accuracy、hammingLoss、precision、recall、f1Measure、precisionByLabel、recallByLabel、f1MeasureByLabe、microPrecision、microRecall、microF1Measure。
其具体用法如下:
import os
from pyspark.sql import SparkSession
from pyspark.ml.classification import *
from sklearn.datasets import *
from pyspark.ml.evaluation import *
from pyspark.ml.linalg import Vectors
import pandas as pd
import numpy as np
from skmultilearn.problem_transform import BinaryRelevance #基于问题转化
from sklearn.tree import DecisionTreeClassifier
X,y=make_multilabel_classification(n_samples=1000,n_features=20,
n_classes=5,n_labels=2,
allow_unlabeled=False)
classifier=BinaryRelevance(DecisionTreeClassifier(max_depth=5))
classifier.fit(X,y)
y_pred=classifier.predict(X).toarray()
#为了满足MultilabelClassificationEvaluator,需要对y和y_pred的形式进行处理
y=np.where(y==1)
y_pred=np.where(y_pred==1)
data=[([],[]) for _ in range(X.shape[0])]
for idx,val in enumerate(y[0]):
data[val][0].append(float(y[1][idx]))
for idx,val in enumerate(y_pred[0]):
data[val][1].append(float(y_pred[1][idx]))
spark=SparkSession.builder.appName('ml').getOrCreate()
data=spark.createDataFrame(data,['label','prediction'])
evaluator=MultilabelClassificationEvaluator(metricName='accuracy')
evaluator.evaluate(data) #0.726