【机器学习】Spark ML 对数据进行规范化预处理 StandardScaler 与向量拆分

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,5000CU*H 3个月
简介: 标准化Scaler是数据预处理技术,用于将特征值映射到均值0、方差1的标准正态分布,以消除不同尺度特征的影响,提升模型稳定性和精度。Spark ML中的StandardScaler实现此功能,通过`.setInputCol`、`.setOutputCol`等方法配置并应用到DataFrame数据。示例展示了如何在Spark中使用StandardScaler进行数据规范化,包括创建SparkSession,构建DataFrame,使用VectorAssembler和StandardScaler,以及将向量拆分为列。规范化有助于降低特征重要性,提高模型训练速度和计算效率。

什么数据规范化?

规范化(Normalization)是一种数据预处理技术,用于将不同范围的特征值映射到相同的范围内。其中,StandardScaler 是一种规范化的方法,它将特征值转换为均值为 0、方差为 1 的标准正态分布。

需要注意的是,StandardScaler 的使用需要对数据进行归一化,以确保每个特征值的范围相同。否则,具有较大范围的特征值可能会在标准化后对结果产生较大的影响。

为什么要对数据进行规范化处理?

对数据进行规范化处理有以下几个原因:

  1. 降低特征的重要性:在机器学习中,不同的特征通常具有不同的尺度和范围,这可能会导致某些特征在预测中具有较大的重要性。通过规范化处理,可以将所有特征缩放到相同的尺度和范围,降低特征的重要性,从而提高模型的稳定性和可靠性。

  2. 提高模型的精度:在某些机器学习算法中,例如K均值聚类和支持向量机,距离和相似度的度量对算法的结果产生很大影响。如果特征具有不同的尺度和范围,可能会导致距离和相似度的度量产生偏差,从而降低模型的精度。通过规范化处理,可以消除这种偏差,提高模型的精度。

  3. 加速模型的训练:在机器学习中,通常需要对数据进行多次迭代来训练模型。如果特征具有不同的尺度和范围,可能会导致收敛速度较慢,从而延长训练时间。通过规范化处理,可以提高收敛速度,加速模型的训练。

  4. 优化计算资源的利用:在大数据环境中,对数据进行规范化处理可以使得机器学习算法在分布式计算环境中更好地运行,从而充分利用计算资源,提高计算效率。

进行规范化处理可以提高模型的稳定性、可靠性、精度、训练速度和计算效率,从而更好地应用于实际场景中。

Spark ML 之 StandardScaler

StandardScaler 是 Spark ML 中的一个数据转换器,用于对数据进行规范化处理。它可以将数据集的每个特征按照均值和标准差进行转换,使得所有特征具有相同的尺度和范围,从而降低特征的重要性,提高模型的稳定性和可靠性。

Spark ML 应用示例

首先,引入 Spark ML 的依赖,这里不做过多的赘述了。

        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-mllib_2.12</artifactId>
            <version>3.0.0</version>
        </dependency>

1.创建 SparkSession 对象

        val spark: SparkSession = SparkSession
                .builder
                .master("local[*]")
                .appName("Test")
                .getOrCreate()

2.创建一个示例数据集,格式为 DataFrame

        import spark.implicits._

        val data: DataFrame = Seq(
            (1.0, 2.0, 3.0),
            (2.0, 3.0, 4.0),
            (3.0, 4.0, 5.0)
        ).toDF("feature1","feature2","feature3")

3.将 DataFrame 转换为向量

        val assembler: VectorAssembler = new VectorAssembler()
                .setInputCols(Array("feature1", "feature2", "feature3"))
                .setOutputCol("features")

        val assemblerData: DataFrame = assembler.transform(data)

将所有的列都作为输入列]("feature1", "feature2", "feature3"),转换为特征向量。

VectorAssembler 是 Spark MLlib 中的一个Transformer,其作用是将多个列组合成一个特征向量。

在机器学习中,通常需要将多个特征组合在一起作为模型的输入,而 VectorAssembler 可以很方便地完成这个任务,它可以将数据集中的多个列组合成一个稠密的向量或者一个稀疏的向量,这取决于输入的列和参数设置。

4.创建 StandardScaler 实例,并设置输入和输出列

        val scaler = new StandardScaler()
                .setInputCol("features")
                .setOutputCol("scaled_features")
                .setWithMean(true)
                .setWithStd(true)

参数说明:

  • .setInputCol("features") 设置输入列的名称为 "features",即指定要对哪个列的数据进行规范化处理。这里的 "features" 是我们在转换向量时 DataFrame 的输出列名。

  • .setOutputCol("scaled_features") 设置输出列的名称为 "scaled_features",即指定规范化处理后的数据要保存到哪个列。这个列名可以根据需要自行命名,不一定非得叫 "scaled_features"

  • .setWithMean(true) 设置是否将数据中心化,即将数据的均值设为 0。默认值为 false,即不中心化。

  • .setWithStd(true) 设置是否将数据标准化,即将数据除以标准差。默认值为 true,即标准化数据,使得数据的均值为 0,方差为 1,从而将数据转化为标准正态分布。

中心化就是将数据减去其均值,使其以 0 为中心点,也称为零均值化。具体来说,对于一个向量 X,其中心化后的向量 X' 可以表示为: X' = X - mean(X)
其中 mean(X) 是向量 X 的均值。中心化后的向量 X' 的均值将会变为 0,因为:mean(X') = mean(X - mean(X)) = mean(X) - mean(X) = 0
这样做的好处是,消除了数据的平移性,将数据转化为以 0 为中心的分布,便于不同指标之间的比较和加权。同时,中心化并不会改变数据的比例关系,也就是说,中心化后的数据与原始数据之间的关系不会发生变化,因此,中心化操作并不会影响模型的精度和稳定性,反而可以提高模型的精度和稳定性。

5.对数据集进行拟合与转换

        val scalerModel = scaler.fit(assemblerData)
        val scaledData = scalerModel.transform(assemblerData)

6.输出处理完成的数据

        scaledData.show(false)

输入结果如下所示:

+--------+--------+--------+-------------+----------------+
|feature1|feature2|feature3|features     |scaled_features |
+--------+--------+--------+-------------+----------------+
|1.0     |2.0     |3.0     |[1.0,2.0,3.0]|[-1.0,-1.0,-1.0]|
|2.0     |3.0     |4.0     |[2.0,3.0,4.0]|[0.0,0.0,0.0]   |
|3.0     |4.0     |5.0     |[3.0,4.0,5.0]|[1.0,1.0,1.0]   |
+--------+--------+--------+-------------+----------------+

将向量 Vector 拆分为列

从上面的示例中,可以看到 scaled_features 列就是规范化处理后的数据,但还需要进一步处理该数据,取到每列数据。

因为在进行数据预测时,我们使用的特征一般都是整型或浮点型,然而我们模型训练后的数据 scaled_features 列是一个向量类型的数据,注意,它不是一个数组!那么该如何取出该列中的每个元素呢?

在 Spark 3.0 以后提供了 vector_to_array() 方法用于将向量转换为数组,如下所示:

        val dataFrame: DataFrame = scaledData
                .withColumn("new_scaled_features", vector_to_array(col("scaled_features")))

        dataFrame.show(false)

其中 withColumn() 方法将添加一个新的名为 "new_scaled_features" 的列到新的 DataFrame 中,将 "scaled_features" 列向量转换成数组作为值。

输出结果如下所示:

+--------+--------+--------+-------------+----------------+-------------------+
|feature1|feature2|feature3|features     |scaled_features |new_scaled_features|
+--------+--------+--------+-------------+----------------+-------------------+
|1.0     |2.0     |3.0     |[1.0,2.0,3.0]|[-1.0,-1.0,-1.0]|[-1.0, -1.0, -1.0] |
|2.0     |3.0     |4.0     |[2.0,3.0,4.0]|[0.0,0.0,0.0]   |[0.0, 0.0, 0.0]    |
|3.0     |4.0     |5.0     |[3.0,4.0,5.0]|[1.0,1.0,1.0]   |[1.0, 1.0, 1.0]    |
+--------+--------+--------+-------------+----------------+-------------------+

其中 new_scaled_features 列就是我们转换成数组之后的列,现在我们就可以对其进行直接提取啦,如下所示:

        dataFrame
                .select(
                    col("new_scaled_features").getItem(0).alias("first"),
                    col("new_scaled_features").getItem(1).alias("second"),
                    col("new_scaled_features").getItem(2).alias("third")
                )
                .show(false)

输出结果如下:

+-----+------+-----+
|first|second|third|
+-----+------+-----+
|-1.0 |-1.0  |-1.0 |
|0.0  |0.0   |0.0  |
|1.0  |1.0   |1.0  |
+-----+------+-----+

向量拆分技巧 GOT!

相关文章
|
25天前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
45 3
|
17天前
|
机器学习/深度学习 存储 人工智能
揭秘机器学习背后的神秘力量:如何高效收集数据,让AI更懂你?
【10月更文挑战第12天】在数据驱动的时代,机器学习广泛应用,从智能推荐到自动驾驶。本文以电商平台个性化推荐系统为例,探讨数据收集方法,包括明确数据需求、选择数据来源、编写代码自动化收集、数据清洗与预处理及特征工程,最终完成数据的训练集和测试集划分,为模型训练奠定基础。
32 3
|
18天前
|
机器学习/深度学习 算法 Python
“探秘机器学习的幕后英雄:梯度下降——如何在数据的海洋中寻找那枚失落的钥匙?”
【10月更文挑战第11天】梯度下降是机器学习和深度学习中的核心优化算法,用于最小化损失函数,找到最优参数。通过计算损失函数的梯度,算法沿着负梯度方向更新参数,逐步逼近最小值。常见的变种包括批量梯度下降、随机梯度下降和小批量梯度下降,各有优缺点。示例代码展示了如何用Python和NumPy实现简单的线性回归模型训练。掌握梯度下降有助于深入理解模型优化机制。
25 2
|
2月前
|
机器学习/深度学习 数据采集 监控
探索机器学习:从数据到决策
【9月更文挑战第18天】在这篇文章中,我们将一起踏上一段激动人心的旅程,穿越机器学习的世界。我们将探讨如何通过收集和处理数据,利用算法的力量来预测未来的趋势,并做出更加明智的决策。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和思考方式。
|
21天前
|
机器学习/深度学习 算法 数据处理
EM算法对人脸数据降维(机器学习作业06)
本文介绍了使用EM算法对人脸数据进行降维的机器学习作业。首先通过加载ORL人脸数据库,然后分别应用SVD_PCA、MLE_PCA及EM_PCA三种方法实现数据降维,并输出降维后的数据形状。此作业展示了不同PCA变种在人脸数据处理中的应用效果。
27 0
|
2月前
|
机器学习/深度学习 数据采集 算法
利用未标记数据的半监督学习在模型训练中的效果评估
本文将介绍三种适用于不同类型数据和任务的半监督学习方法。我们还将在一个实际数据集上评估这些方法的性能,并与仅使用标记数据的基准进行比较。
168 8
|
28天前
|
机器学习/深度学习 算法 数据建模
【机器学习】类别不平衡数据的处理
【机器学习】类别不平衡数据的处理
|
3月前
|
缓存 开发者 测试技术
跨平台应用开发必备秘籍:运用 Uno Platform 打造高性能与优雅设计兼备的多平台应用,全面解析从代码共享到最佳实践的每一个细节
【8月更文挑战第31天】Uno Platform 是一种强大的工具,允许开发者使用 C# 和 XAML 构建跨平台应用。本文探讨了 Uno Platform 中实现跨平台应用的最佳实践,包括代码共享、平台特定功能、性能优化及测试等方面。通过共享代码、采用 MVVM 模式、使用条件编译指令以及优化性能,开发者可以高效构建高质量应用。Uno Platform 支持多种测试方法,确保应用在各平台上的稳定性和可靠性。这使得 Uno Platform 成为个人项目和企业应用的理想选择。
52 0
|
3月前
|
机器学习/深度学习 缓存 TensorFlow
TensorFlow 数据管道优化超重要!掌握这些关键技巧,大幅提升模型训练效率!
【8月更文挑战第31天】在机器学习领域,高效的数据处理对构建优秀模型至关重要。TensorFlow作为深度学习框架,其数据管道优化能显著提升模型训练效率。数据管道如同模型生命线,负责将原始数据转化为可理解形式。低效的数据管道会限制模型性能,即便模型架构先进。优化方法包括:合理利用数据加载与预处理功能,使用`tf.data.Dataset` API并行读取文件;使用`tf.image`进行图像数据增强;缓存数据避免重复读取,使用`cache`和`prefetch`方法提高效率。通过这些方法,可以大幅提升数据管道效率,加快模型训练速度。
45 0
|
3月前
|
机器学习/深度学习 SQL 数据采集
"解锁机器学习数据预处理新姿势!SQL,你的数据金矿挖掘神器,从清洗到转换,再到特征工程,一网打尽,让数据纯净如金,模型性能飙升!"
【8月更文挑战第31天】在机器学习项目中,数据质量至关重要,而SQL作为数据预处理的强大工具,助力数据科学家高效清洗、转换和分析数据。通过去除重复记录、处理缺失值和异常值,SQL确保数据纯净;利用数据类型转换和字符串操作,SQL重塑数据结构;通过复杂查询生成新特征,SQL提升模型性能。掌握SQL,就如同拥有了开启数据金矿的钥匙,为机器学习项目奠定坚实基础。
37 0