PySpark分类模型简明教程

一、PySpark分类模型

PySpark提供了多种分类模型,这些模型可以用于解决不同场景下的分类问题。以下是一些常见的PySpark分类模型:

(1)逻辑回归(Logistic Regression):

  • 逻辑回归是一种广泛用于分类问题的线性模型,特别适用于二分类问题。
  • 在PySpark中,逻辑回归可以通过pyspark.ml.classification.LogisticRegression类来实现。
  • 它不仅可以用于二分类,通过设置family参数为"multinomial",还可以用于多分类问题。

(2)决策树(Decision Tree):

  • 决策树是一种强大的非线性分类技术,可以表达复杂的非线性模式和特征相互关系。
  • 在PySpark中,决策树分类器可以通过pyspark.ml.classification.DecisionTreeClassifier类来实现。
  • 决策树模型易于理解和解释,并且可以处理类别或数值特征,不需要输入数据归一化或标准化。

(3)随机森林(Random Forest):

  • 随机森林是一种集成学习方法,通过构建多个决策树并将它们的预测结果进行组合来提高分类性能。
  • 在PySpark中,随机森林分类器可以通过pyspark.ml.classification.RandomForestClassifier类来实现。
  • 随机森林通常比单个决策树具有更好的泛化能力,因为它减少了过拟合的风险。

(4)梯度提升树(Gradient-Boosted Trees, GBTs):

  • 梯度提升树是另一种集成学习方法,它通过迭代地构建决策树来优化损失函数,从而改进模型的分类性能。
  • 在PySpark中,梯度提升树分类器可以通过pyspark.ml.classification.GBTClassifier类来实现。
  • GBTs在许多分类任务上表现出色,特别是当数据集具有复杂的非线性关系时。

(5)朴素贝叶斯(Naive Bayes):

  • 朴素贝叶斯是一种基于贝叶斯定理和特征条件独立假设的分类方法。
  • 在PySpark中,朴素贝叶斯分类器可以通过pyspark.ml.classification.NaiveBayes类来实现。
  • 尽管它假设特征之间条件独立,但在许多实际应用中,朴素贝叶斯分类器仍然表现出良好的性能,并且具有高效和并行的优点。

(6)多层感知器(Multilayer Perceptron, MLP):

  • 多层感知器是一种前馈人工神经网络模型,可以用于分类和回归任务。
  • 在PySpark中,多层感知器分类器可以通过pyspark.ml.classification.MultilayerPerceptronClassifier类来实现。
  • MLP能够捕捉数据中的复杂非线性关系,并且通过训练可以学习到有效的特征表示。

(7)线性支持向量机(Linear Support Vector Machine, Linear SVM):

  • 线性支持向量机是一种基于间隔最大化的分类方法,它试图找到一个超平面来将不同类别的数据分开。
  • 在PySpark中,虽然MLlib库中没有直接提供Linear SVM的类,但可以通过设置逻辑回归的某些参数(如损失函数为hinge loss)来近似实现线性SVM的功能。

需要注意的是,以上分类模型的选择应根据具体问题的特点、数据集的大小和分布以及计算资源等因素进行综合考虑。在实际应用中,可能需要通过交叉验证等方法来评估不同模型的性能,并选择最适合当前问题的模型。

二、PySpark集群介绍

  Spark集群是一种分布式计算框架,它基于内存计算,提供了高效的数据抽象和并行计算能力,能够处理大规模数据集的批处理和实时处理任务。Spark采用内存存储中间计算结果,可减少迭代运算的磁盘I/O,并通过并行计算有向无环图的优化,使其运行速度比MapReduce快100倍;Spark可以使用Hadoop YARN和Apache Mesos作为其资源管理和调度器,可以从多种数据源读取数据,如HDFS、HBase、MySQL等。
  PySpark则是Spark的Python API,允许Python开发者利用Spark的强大功能进行数据处理和分析。本案例采用PySpark大数据集群做数据分析与挖掘,使用HDFS作为文件存储系统。PySpark由多个组件构成,包括Spark SQL、Spark Streaming、MLlib(机器学习库)和GraphX(图计算库)等。
  本案例部署了3个节点的完全分布式集群,具体的开发环境如下:

节点/组件/安装包版本备注
名称节点192.168.126.10master
数据节点192.168.126.10slave1
数据节点192.168.126.10slave2
JDKjdk-8u281Java运行环境,Spark的运行需要JDK的支持
Hadoophadoop-3.1.4提供HDFS、Hive运行环境支持。HDFS系统访问端口为:hdfs://192.168.126.10:9000
pysparkspark-3.4.3-bin-hadoop3.tgzSpark集群的master节点的地址和端口为:spark://192.168.126.10:7077
MySQL5.7.18存储数据分析结果,端口:3306,用户名:root,密码:123456
pythonPython-3.9.0.tgz3.9.0版本的Python
MySQL Connectormysql-connector-java-5.1.32-bin.jarSpark 连接MySQL的驱动
IntelliJ IDEAUltimate 2020.3编程工具IDEA

三、分类模型应用案例:泰坦尼克号乘客幸存预测

  本案例包括两个数据集,一个是训练集:titanic.csv,另外一个是待预测数据集:titanic_pred.csv。训练集:titanic.csv各个字段含义如下:

  • PassengerId:整型(integer),代表乘客的ID,递增变量,一般来说对预测无帮助。
  • Pclass:整型(integer),船票仓位等级,代表乘客的社会经济状态,1代表Upper, 2代表Middle, 3代表Lower
  • Name:字符型(string),代表乘客姓名,一般来说对预测无帮助。
  • Sex:字符型(string),代表乘客性别,female代表女性,male代表男性。
  • Age:数值类型(double),代表乘客年龄,其中有null,即有缺失值。
  • Sibsp:整型(integer),代表兄弟姐妹及配偶的个数,其中Sib代表Sibling,即兄弟姐妹;Sp代表Spouse,即配偶。
  • Parch:整型(integer),代表父母或子女的个数,其中Par代表Parent,即父母;Ch代表Child,即子女。
  • Ticket:字符型(string),代表乘客的船票号,一般来说对预测无帮助。
  • Fare:数值类型(double),代表乘客的船票价格。
  • Cabin:字符型(string),代表乘客所在的舱位,有缺失值。
  • Embarked:字符型(string),代表乘客登船口岸。
  • Survived:整型(integer),代表 该乘客是否幸存,其中1表示幸存,0表示遇难。该字段为数据集的标签,即目标值。

  训练集:titanic.csv的部分数据如下图所示。
在这里插入图片描述
  待预测数据集:titanic_pred.csv比训练集少了一个字段Survived,需要分类模型预测。

1.数据导入

  两个数据集存放在HDFS的/data/目录下,配置Spark应用程序,导入训练集titanic.csv。

from pyspark import SparkConf
from pyspark.ml.feature import StringIndexer, VectorAssembler
from pyspark.sql import SparkSession, Row
from pyspark.sql.functions import *
from pyspark.ml.classification import *
from pyspark.ml.evaluation import *
from pyspark.ml import Pipeline
import matplotlib
# 设置一个支持GUI的后端,用于在IDEA绘图
matplotlib.use('TkAgg')  # 或者 'Qt5Agg', 'GTK3Agg' 等,用于在IDEA绘图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# -------------------配置Spark应用程序-------------
conf = SparkConf().setAppName("分类模型:泰坦尼克号幸存者分析").setMaster('spark://192.168.126.10:7077')
sc = SparkContext.getOrCreate(conf)
spark = SparkSession(sc)
# -----------------1.数据获取-------------------
filename = "titanic.csv"
titanic = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True,
                         inferSchema=True)  # 训练集包含标题行,inferSchema=True自动推断数据类型
titanic.show(5)
titanic.describe().show()  # 查看数据集的基本数据信息
titanic.printSchema()  # 输出数据集的结构
print(f"训练数据集总的记录数:{titanic.count()}, 列总数:{len(titanic.columns)}")

  数据集一共有891条记录,12个字段。通过titanic.describe().show()查看数据集的基本数据信息,发现Age只有714条记录,Cabin只有204条记录,即这列的缺失值比较多,尤其是Cabin缺失值非常多,应该删除该列。
在这里插入图片描述
在这里插入图片描述

2.数据分析

  数据分析主要包括集中趋势分析、离中趋势分析和相关分析三大部分。

(1)集中趋势分析
  集中趋势分析主要关注数据的中心或平均位置,通过统计指标来表示数据的集中趋势。常用的统计指标包括:

  • 平均数(Mean):所有数值之和除以数值的数量,是反映数据集中心趋势的常用指标。但需注意,平均数对异常值较为敏感。
  • 中数(Median):将数据从小到大排列后,位于中间的数。如果数据量是偶数,则中数是中间两个数的平均值。中数对异常值不敏感,能更好地反映数据的中心位置。
    众数(Mode):数据集中出现次数最多的数。一个数据集可能有多个众数或没有众数(如所有数据都不相同)。
  • 四分位数(Quartiles):将数据分成四等份的数值点,每部分包含四分之一的数据。四分位数有助于了解数据的分布情况。

(2)离中趋势分析
  离中趋势分析主要关注数据的离散程度或波动大小,通过统计指标来研究数据的离中趋势。常用的统计指标包括:

  • 全距(Range):数据集中的最大值与最小值之差,反映了数据的最大波动范围。
  • 四分差(Interquartile Range, IQR):第三四分位数与第一四分位数之差,用于描述中间50%数据的波动范围。
  • 平均差(Mean Deviation):各数值与平均数的差的绝对值的平均数,反映了数值与平均数的平均偏离程度。
  • 方差(Variance):各数值与平均数之差的平方的平均数,用于度量数据集的波动程度。方差越大,表示数据越分散。
  • 标准差(Standard Deviation):方差的平方根,也是度量数据离散程度的常用指标。标准差越小,说明数据越稳定。
  • 变异系数(Coefficient of Variation, CV):标准差除以平均数,用于比较不同数据集之间的离散程度。

(3)相关分析
  相关分析探讨数据之间是否具有统计学上的关联性。这种关系既包括两个数据之间的单一相关关系,也包括多个数据之间的多重相关关系。常用的统计指标和工具包括:

  • 相关系数(Correlation Coefficient):用于量化两个变量之间的线性相关程度。常用的相- - 关系数有皮尔逊相关系数(Pearson’s r)、斯皮尔曼等级相关系数(Spearman’s rho)和肯德尔等级相关系数(Kendall’s tau)等。
  • 散点图(Scatter Plot):一种图形化表示两个变量之间关系的工具,可以直观地看出变量之间的相关性。
  • 回归分析(Regression Analysis):在相关分析的基础上,进一步探讨一个或多个自变量(X)与一个因变量(Y)之间的数量关系。通过回归方程,可以预测因变量的值。
      通过集中趋势分析、离中趋势分析和相关分析,可以全面了解数据的分布特征、离散程度和变量之间的关系,为后续的数据分析和决策提供支持。
      本案例主要目的是演示分类模型的应用,并没有做全部的集中趋势分析、离中趋势分析和相关分析,只是做了一些简单的数据分析。
      上一节已经查看了数据集的基本数据信息,本节先抽取部分字符串类型列数据,生成描述性统计信息,再抽取部分数值类型列数据,生成描述性统计信息。describe()方法通常用于数值型数据的描述性统计。
    在这里插入图片描述
      然后通过统计汇总,分析是否幸存(Survived)与性别(Sex)和社会经济状态(Pclass)、家庭成员数(Parch、SibSp)等因素的关系。
# ---------------2.数据分析-----------------------------
# 计算基本的统计描述信息
print("\n-------2.数据分析---------\n")
titanic.describe('Age', 'Pclass', 'SibSp', 'Parch').show()  # 抽取部分字符串型列数据,生成描述性统计信息
titanic.describe('Sex', 'Cabin', 'Embarked', 'Fare', 'Survived').show()  # 抽取部分数值型列数据,生成描述性统计信息

# 对Sex和Survived两个字段分组 求乘客数,并将结果列count(PassengerId)重命名为count,最后按照Sex排序。
sex_counts = titanic.groupBy('Sex', 'Survived') \
    .agg({'PassengerId': 'count'}) \
    .withColumnRenamed("count(PassengerId)", "count") \
    .orderBy('Sex', 'Survived') \
    .toPandas()  # 转换为pandas的DataFrame,方便用pandas的matplotlib可视化
print("\n对性别Sex和Survived两个字段分组 求乘客数\n", sex_counts)

male_vs = sex_counts[sex_counts['Survived'] == 1]['count']  # 提取 幸存者 的男女人数
print("\n幸存者男女人数:\n", male_vs)
female_vs = sex_counts[sex_counts['Survived'] == 0]['count']  # 提取 遇难者 的男女人数
print("\n遇难者男女人数:\n", female_vs)

# ---------------绘图------
plt.bar(x=['female', 'male'], height=male_vs, width=0.35, label='幸存者')
plt.bar(x=['female', 'male'], height=female_vs, width=0.35, bottom=male_vs, label='遇难者')
plt.xlabel('性别')
plt.legend()
plt.show()

# 对船票仓位等级Pclass和Survived两个字段分组求乘客数
pclass_counts = titanic.groupBy('Pclass', 'Survived') \
    .agg({'PassengerId': 'count'}) \
    .withColumnRenamed("count(PassengerId)", "count") \
    .orderBy('Pclass', 'Survived') \
    .toPandas()
print("\n对船票仓位等级Pclass和Survived两个字段分组求乘客数:\n", pclass_counts)

# 对父母/孩子Parch和Survived两个字段分组求乘客数
parch_counts = titanic.groupBy('Parch', 'Survived') \
    .agg(count("PassengerId").alias("count")) \
    .orderBy('Parch', 'Survived') \
    .toPandas()
print("\n对父母/孩子个数Parch和Survived两个字段分组求乘客数:\n", parch_counts)

# 对兄弟姐妹/配偶数SibSp和幸存Survived两个字段分组求乘客数
sibsp_counts = titanic.groupBy('SibSp', 'Survived') \
    .agg(count("PassengerId").alias("count")) \
    .orderBy('SibSp', 'Survived') \
    .toPandas()
print("\n对兄弟姐妹/配偶数SibSp和Survived两个字段分组求乘客数:\n", sibsp_counts)

  性别和是否幸存的关系如下:
在这里插入图片描述
  有上图可知,女性(female)的幸存几率比男性高。可以再绘制Survived和社会经济状态(Pclass)、家庭成员数(Parch、SibSp)等的关系分析图。

3.数据清洗与处理

  由于舱位Cabin列的缺失值很多,已经失去了数据分析的价值,因此删除该列。年龄Age有177个缺失值,用年龄的平均值填充,登船口岸Embarked有2个缺失值,用众数港口s填充。
  船票号Ticket与幸存没有什么关系,删除该列。姓名name列也可以删除。

# -------------3.训练集 数据清洗与处理:缺失值处理------------------------
print("\n---3.训练集 数据清洗与处理:缺失值处理---\n训练集年龄Age字段的描述性统计信息:\n")
titanic.describe('Age').show()  # 查看年龄Age的描述性统计信息
avg_age = titanic.agg(mean('Age')).collect()[0][0]  # 计算年龄的平均值
print("训练集平均年龄为:", avg_age)

titanic = titanic.fillna({'Age': avg_age})  # 用年龄Age的平均值替换缺失值。
titanic = titanic.withColumn('Age', round('Age', 0))  # round('Age', 0)对列Age四舍五入,然后再更新,格式和目标列一致,如56.0
print("\n用年龄平均值填充年龄列的缺失值后,训练集数据如下:")
titanic.show(5)
titanic.describe('Age').show()

titanic = titanic.fillna({'Embarked': 'S'})  # 用登陆港口‘S’替换Embarked列的缺失值
titanic = titanic.drop('Cabin')  # 删除舱位Cabin列,该列与幸存没关系
titanic = titanic.drop('Ticket')  # 删除船票号Ticket列,该列与幸存没关系。
print("数据清洗和处理(填充登陆港口Embarked缺失值,删除舱位Cabin和票号Ticket)后的训练集:")
titanic.show(5)
titanic.printSchema()

4.特征工程

4.1 数值化字符串类型的列

  由于机器学习不能直接处理字符串类型数据,因此将将字符串类型的列Embarked 和Sex数值化。

# ----------------------4. 特征工程---------------------
print("--------4. 特征工程--------------")
#   将字符串类型的列数值化(机器学习算法不能直接处理字符串列数据)。先使用StringIndexer类(标签索引转换器)创建一个模型实例
label_index = StringIndexer(inputCols=['Embarked', 'Sex'], outputCols=['iEmbarked', 'iSex'])
# 让模型学习'Embarked', 'Sex'列中所有不同的字符串值,分别为它们分配一个唯一的整数标识符。  拟合过程会构建一个从字符串到整数的映射关系。
label_model = label_index.fit(titanic)
#  使用拟合好的模型对训练数据集titanic进行转换。transform()方法会根据前面构建的映射关系,将'Embarked', 'Sex'列中的每个字符串值替换为对应的整数标识符
titanic = label_model.transform(titanic)

print("将Embarked和Sex数值化后的训练集如下:")
titanic.show(5, False)

  程序运行结果如下:
在这里插入图片描述

4.2 选择特征,并向量化

  选择数值型的字段,用于模型训练和模型应用的Survived值预测。选择的特征有:[‘Pclass’, ‘iSex’, ‘Age’, ‘SibSp’, ‘Parch’, ‘Fare’, ‘iEmbarked’],将其向量化,最后将向量化后的数据集划分为训练集(70%)和测试集(30%)。

# 选择多个特征列,并将其转换为向量列:features
df_assembler = VectorAssembler(inputCols=['Pclass', 'iSex', 'Age', 'SibSp', 'Parch', 'Fare', 'iEmbarked'],
                               outputCol='features')  # VectorAssembler:将给定的字段列表(类型必须为数值)转换为一个向量列
titanic_assembled = df_assembler.transform(titanic)  # 对数值化后的数据集titanic进行向量化转换
print("将多个数值型特征向量化后的训练数据:")
titanic_assembled.show(5, False)
titanic_assembled['features',].show(5)
titanic_assembled['Survived',].show(5)
train, test = titanic_assembled.randomSplit([0.7, 0.3], seed=3)  # 将数据集划分为训练集(70%)和测试集(30%)

  向量化后的数据集titanic如下所示:
在这里插入图片描述
  后面的模型训练,主要是使用向量化后的特征列:features,以及标签列:Survived。

4.3 待预测数据集的预处理

  待预测数据集titanic_pred.csv的数据预处理过程也是按照同样的流程操作。
(1)导入数据,填充缺失值和删除无关列。

filename = "titanic_pred.csv"
newData = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True, inferSchema=True)  # 数据集包含标题行
print("待预测数据集的行数:", newData.count(), ",待预测数据集的列总数:", len(newData.columns))

print("-------5.待预测数据集test的数据处理----------------")
newData = newData.fillna({'Age': 29.699, 'Embarked': 'S'})  # 用平均值29.699填充Age列的空值,S填充Embarked空值
newData = newData.withColumn('Age', round('Age', 0))  # 对列Age四舍五入,保留0个小数,然后重新赋值给Age
newData = newData.drop('Cabin', 'Ticket')  # 删除两列数据
print("Age,Embarked缺失值填充,Cabin,Ticket删除后的待预测数据集:")
newData.show(5)

(2)数值化字符串类型的列
  使用前面创建并拟合好的数值化模型label_model,数值化列’Embarked’, ‘Sex’。

#  将字符型数据 数值化
newData = label_model.transform(newData)  # 使用前面的数值化模型label_model,数值化列'Embarked', 'Sex'
print("字符型列的数据数值化后的待预测数据集:")
newData.show(5)

  数值化后的待预测数据集titanic_pred部分数据如下所示。
在这里插入图片描述

(3)选择特征,并向量化
  为了方便查看预测结果,将乘客编号PassengerId加入到选择的特征,但该列不参与向量化,因为前面构建的向量化模型df_assembler并没有考虑该列。

# 选择特征
features = ['Pclass', 'iSex', 'Age', 'SibSp', 'Parch', 'Fare', 'iEmbarked']
newData_features = newData[['PassengerId'] + features]  # 加上乘客编号PassengerId,构造新的dataframe,带有乘客编号便于查看预测结果。
print("选择特征后的待预测数据,没有标签Survived:")
newData_features.show(5)

#  将多个列转换为向量
newData_assembled = df_assembler.transform(newData_features)  # 使用前面构建的向量化模型df_assembler,将newData_features数据集向量化
print("将选择的特征向量化后的待预测数据集:")
newData_assembled.show(5)

  向量化后的待预测数据集部分数据如下所示。
在这里插入图片描述
  此时,使用后面训练好的分类模型,根据向量化列features,就可以预测乘客是否幸存Survived。

5. 构建分类模型:逻辑回归模型LogisticRegression

构建逻辑回归模型,并用训练集train训练模型,训练好的逻辑回归模型为:lgModel 。

# 6.1 模型构建及训练
lg = LogisticRegression(labelCol='Survived', featuresCol='features')  # 构建逻辑回归模型,确定标签为Survived列,特征为features列
lgModel = lg.fit(train)  # 模型训练

6. 模型评估

  模型评估有两种方法,一种是内部评估法,另外一种是外部评估法。
方法一:内部评估(In-sample Evaluation)

  • 数据来源:内部评估使用模型训练时所用的数据集(训练集)或训练数据的一个子集来进行评估。
  • 评估目的:主要用于在模型训练过程中监控模型的性能,以便进行模型选择和调优。它可以帮助开发者了解模型在已知数据上的表现,但可能无法准确反映模型在未知数据上的泛化能力。
  • 可靠性:由于评估数据与训练数据相同或高度相似,内部评估结果可能过于乐观,存在过拟合的风险。因此,它通常不能作为模型最终性能的可靠指标。
# 6.2 模型测试评估:
# 方法一:内部评估
print("逻辑回归分类模型的 假正率FPR和真正率TPR(召回率),ROC曲线以FPR为横轴,TPR为纵轴:")
trainingSummary = lgModel.summary
trainingSummary.roc.show()
print('逻辑回归模型准确率:', trainingSummary.accuracy)
print('每个标签(类别)的召回率:', trainingSummary.recallByLabel)
print('加权平均召回率:', trainingSummary.weightedRecall)
print('每个标签(类别)的精度:', trainingSummary.precisionByLabel)
print('加权平均精度:', trainingSummary.weightedPrecision)

模型评估结果如下:
在这里插入图片描述

方法二:外部评估(Out-of-sample Evaluation)

  • 数据来源:外部评估使用模型训练过程中未使用过的数据集(如测试集或验证集)来进行评估。这些数据集与训练数据独立,模拟了模型在实际应用中的未知数据环境。
  • 评估目的:外部评估旨在评估模型在未知数据上的泛化能力,即模型能否准确地对新数据进行预测或分类。这是评估模型最终性能的关键步骤。
  • 可靠性:由于评估数据与训练数据独立,外部评估结果更加可靠,能够更准确地反映模型在实际应用中的表现。它是选择最终模型并进行部署的重要依据。

  metricName 参数提供的评估指标有:

  • “f1”:F1分数,是精确率和召回率的调和平均数,对于数据不平衡的情况特别有用。
  • “accuracy”: 准确率,即正确预测的样本数与总样本数的比例。
  • weightedPrecision”:加权精确率,考虑了每个类别的支持度(即每个类别的样本数)。
  • weightedRecall”:加权召回率,同样考虑了每个类别的支持度。
  • weightedTruePositiveRate”:加权真正率(TPR),也叫做灵敏度或召回率,但在这里是加权形式。
  • weightedFalsePositiveRate”:加权假正率(FPR),是误报率的加权形式。
  • weightedFMeasure”:加权F-measure,是精确率和召回率的加权调和平均数。
  • truePositiveRateByLabel”:每个类别的真正率(TPR)。
  • falsePositiveRateByLabel”:每个类别的假正率(FPR)。
  • precisionByLabel”:每个类别的精确率。
  • recallByLabel”:每个类别的召回率。
  • fMeasureByLabel”:每个类别的F-measure。
# 方法二:外部评估
lg_predictions = lgModel.transform(test)  # 用测试集做预测,用于评估模型
# 多分类模型评估器,需要指定labelCol(真实标签的列名)和predictionCol(模型预测结果的列名),指标metricName名称为准确率accuracy
multi_evaluator = MulticlassClassificationEvaluator(labelCol='Survived',
                                                    predictionCol='prediction',
                                                    metricName='accuracy')
print('逻辑回归模型的准确率为:', multi_evaluator.evaluate(lg_predictions))

multi_evaluator = MulticlassClassificationEvaluator(labelCol='Survived',
                                                    predictionCol='prediction',
                                                    metricName='weightedRecall')
print('加权召回率为:', multi_evaluator.evaluate(lg_predictions))

逻辑回归模型评估结果如下:
在这里插入图片描述

7. 模型应用

  使用训练好的逻辑回归模型lgModel,预测数据集titanic_pred的乘客幸存情况。代码如下:

# 6.3 模型应用:使用训练好的 逻辑回归模型对待预测数据 预测
prediction = lgModel.transform(newData_assembled)  # 应用训练好的逻辑回归模型预测 待预测数据集test
print("\n逻辑回归模型对待预测数据集test的预测结果如下:")
prediction.show(5)
prediction.select(['PassengerId', 'Pclass', 'iSex', 'features', 'prediction']).show(5)  # 抽取部分数据

  预测结果如下:
在这里插入图片描述

  抽取部分列[‘PassengerId’, ‘Pclass’, ‘iSex’, ‘features’, ‘prediction’]的预测数据如下:
在这里插入图片描述

四、其他分类模型

1.决策树模型

  使用前面已经预处理、数值化、向量化的训练数据集train和测试数据集test,可以很方便构建、训练、评估决策树模型,最后用决策树模型预测乘客是否幸存。

# 7.1 模型创建与训练
dTree = DecisionTreeClassifier(labelCol='Survived', featuresCol='features')
treeMode = dTree.fit(train)
# 7.2 模型测试评估:方法二,常用
dt_predictions = treeMode.transform(test)  # 用测试集做预测,用于评估模型
# 多分类模型评估器,需要指定labelCol(真实标签的列名)和predictionCol(模型预测结果的列名),指标metricName名称为准确率
multi_evaluator = MulticlassClassificationEvaluator(labelCol='Survived',
                                                    predictionCol='prediction',
                                                    metricName='accuracy')
print('决策树的准确率为:', multi_evaluator.evaluate(dt_predictions))

# 7.3 模型应用:决策树模型应用,预测
pred = treeMode.transform(newData_assembled)
print("决策树模型对待预测数据集titanic_pred的预测结果如下:")
pred.show(5, False)
pred.select(['Pclass', 'iSex', 'features', 'prediction']).show(5)  # 抽取数据

  模型预测 结果如下:
在这里插入图片描述

2.随机森林树模型

  同理,构建、训练和评估决策树模型,最后用随机森林树模型预测乘客是否幸存。

# ----------------8.其他分类模型:随机森林树模型--------------------------
rfc = RandomForestClassifier(labelCol='Survived', featuresCol='features')  # 构建随机森林树模型
rfcMode = rfc.fit(train)  # 模型训练
rf_pred = rfcMode.transform(test)  # 用训练数据做预测,用于评估模型
multi_evaluator = MulticlassClassificationEvaluator(labelCol='Survived',
                                                    predictionCol='prediction',
                                                    metricName='accuracy')
print('随机森林树算法的准确率:', multi_evaluator.evaluate(rf_pred))

print("随机森林模型对待预测数据集titanic_pred的预测结果如下:")
pred = rfcMode.transform(newData_assembled).select(['PassengerId', 'Pclass', 'iSex', 'prediction'])  # 抽取部分数据
pred.show(5, False)

  随机森森林树模型预测结果如下:
在这里插入图片描述

参考资料:
1.PySpark 大数据机器学习入门案例1 :iris+ ML+Logistics分类:https://www.zhihu.com/tardis/bd/art/612626873?source_id=1001
2.pySpark 机器学习库ml入门(参数调优):https://www.jianshu.com/p/20456b512fa7
3.PySpark 逻辑回归(参数调优):https://zhuanlan.zhihu.com/p/461211990
4.Spark ML LR 用 setWeightCol 解决数据不平衡:https://kelun.blog.csdn.net/article/details/103425926
5.Python——机器学习:不平衡数据集常用处理方法和实例:https://blog.csdn.net/weixin_53848907/article/details/135976144
6.决策树分类器(DecisionTreeClassifier):https://blog.csdn.net/qq_66726657/article/details/132470442
7.戴刚,张良均. PySpark大数据分析与应用. 人民邮电出版社,2024.
8.汪明. PySpark实战. 清华大学出版社,2022

  • 23
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

侧耳倾听童话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值