为机器学习准备数据

已完成

在创建机器学习模型之前,需要准备用于训练和评估它的数据。 数据从其源引入到 Azure Databricks 中,通常作为数据文件。 (可选)可以根据数据文件创建增量表,以简化数据浏览和分析。 引入数据后,数据科学家会为机器学习做好准备。

通常,数据准备涉及两个关键任务:

  • 数据清理:识别和缓解数据中会影响其对机器学习的有用性的问题。
  • 特征工程和预处理:选择和转换适合模型训练的特征。

数据清理

清理数据所需的具体步骤因项目而异,但需要解决的典型问题包括:

  • 不完整的数据:数据通常包括缺少各个字段的记录(通常由 NULL 值的存在指示)。 需要识别缺失值并通过以下方法缓解它们:
    • 用一个合适的值来替换它们,可以是通过在序列中插入一个值、使用平均值(或中值)、或者创建其他合适的值。
    • 完全删除不完整的行(假设这留下了足够的合适的代表性数据进行建模)
  • 错误:数据中出现错误并不少见,这些错误可能由数据输入错误或上游数据处理失败造成。 查找错误可能很困难,通常涉及使用查询和可视化效果对数据进行大量审查,以汇总数据,并查找与给定字段中大多数其他值不一致的值。
  • 离群值:离群值是明显超出(高于或低于)数据统计分布的值。 有时离群值表明错误(例如,某人可能在数值中多打了一个零,或者省略了小数点),而有时它们是与大多数观测值相比异常高或低的真实值。 在任一情况下,极端离群值可能会对机器学习模型的训练产生负面影响;因此,最好将其重置为上限或较低的阈值,或者删除包含数据集离群值的记录来处理它们。
  • 数据类型不正确:机器学习算法对分配给特征值的数据类型可能很敏感。 通常,基于包含错误或空值的文本文件的数据集会错误转换数字字段为字符串数据类型,通常表示离散整数值的值会错误地被转换为十进制数(反之亦然)。 应检查数据的架构,并分配最有效地反映数据值的相应数据类型。
  • 不平衡的数据:如果训练数据对可能遇到的所有不同功能和标签组合具有足够的表示形式,则机器学习训练效果最佳。 在不平衡的数据集中,包含特定分类值或字段组合的记录表示过度;这可能会影响训练算法并将偏差引入模型。 缓解此问题的一种常见方法是,通过包含的重复行对表示不足的值进行过采样,或对过度表示的行进行欠采样(从数据集中删除它们)

在 Azure Databricks 上,检测和解决此类问题的最常见方法是在笔记本文档中编写用于探索和操作数据的代码。 用于处理此类数据的主要类是 Spark 数据帧

例如,以下代码将数据从文本文件加载到数据帧中:

df = spark.read.format("csv").option("header", "true").load("/myfolder/mydata.csv")

或者,如果数据已加载到 Azure Databricks 工作区中的增量表中,则可以使用 SQL 查询将数据加载到数据帧中:

df = spark.sql("SELECT * FROM mytable")

将数据加载到数据帧后,可以使用 Spark SQL 库中的方法和其他函数来浏览和转换数据。 例如,以下代码使用 dropna 方法删除包含 null 值的任何行,并将特定数据类型分配给数据帧中的列。

clean_data = df.dropna().select(col("column1").astype("string"),
                                col("column2").astype("float"))

小窍门

有关 Spark 数据帧功能的详细信息,请参阅 Spark 数据帧文档

特征工程和预处理

确保数据集完成且干净后,可以开始为机器学习准备功能。 特征工程是一种迭代方法,通常涉及一些试验和错误来确定哪些特征列具有预测值,以及如何最好地表示特征。 常见的特征工程和预处理任务包括:

  • 派生新功能:通常可以从现有特征派生新的预测特征。 例如,假设一个数据集包含一个“日期”列,并且你怀疑完整的日期可能不是标识标签的一个重要预测因素,但星期几可能是。 可以创建一个新的 day_of_week 特征派生自日期并测试理论。

  • 离散化数值特征:在某些情况下,当 离散化 为表示特定值范围的类别时,数值可能会证明更具预测性。 例如,可以采用 价格 特征中的数值,并根据适当的阈值将它们分配给 类别。

  • 编码分类特征:许多数据集包括由字符串值表示的分类数据。 但是,大多数机器学习算法最适合使用数值数据。 因此,通常分配数字代码来表示类别而不是字符串。 例如,产品详细信息数据集可能包含一个名为“颜色”的特征,其值为“Green”、“Red”或“Blue”。 可以使用简单的整数代码(例如 0 表示“Green”、 1 表示“Red”)和 2 (对于“Blue”)对这些值进行编码。 或者,可以使用 一种热编码 技术,为每个可能的类别创建新列,并为每个列分配值 10 ,如下所示:

    原始颜色列 绿色 红色
    绿色 1 0 0
    0 0 1
    0 1 0
  • 缩放(标准化)数值:数值数据通常会采用不同的比例或测量单位。 机器学习算法将它们全部处理为绝对数值,具有较大值的特征通常主宰模型的训练。 若要解决此问题,通常缩放所有数值列,以便单个列中的每个值保持相同的比例关系,同时所有数值列都在类似的范围内。 例如,假设数据集包含以米和公斤为单位测量的 长度权重 值。 可以将这两项功能转换为介于 0 和 1 之间的缩放值,如下所示:

    length 重量 scaled_length scaled_weight
    250.0 2.1 0.250 0.210
    176.0 0.9 0.176 0.09

许多机器学习库包括可用于执行常见特征工程任务的类。 例如,Spark MLlib 库包括 StringIndexer 类,可用于对字符串值执行基于整数的简单编码。

from pyspark.ml.feature import StringIndexer

encoder = StringIndexer(inputCol="catCol", outputCol="catColCode")
encoded_data = encoder.fit(data).transform(data)

注释

需要更详细地解释 StringIndexer 代码示例。 Spark MLlib 类可以包含将特定转换操作的算法拟合到某些样本数据的计算器。 在这种情况下,StringIndexer 将一种编码算法拟合到 数据 数据帧中的 catCol 列的离散字符串值上,以确定需要进行的特定计算,以生成一个包含编码值的新 catColCode 列。 评估器的输出是封装评估器定义的函数的转换器,该转换器可以应用于数据并生成新的数据帧。 在此示例中,我们将用于 确定 编码函数的相同数据传递给生成的转换器,以实际 应用 编码。

在 Spark MLLib 中,可以在管道中将一系列计算器和转换器链接在一起,该 管道 执行准备数据所需的所有特征工程和预处理步骤。 管道可以以机器学习算法结束,该算法充当评估程序,以确定需要执行的操作,以便从准备好的特征中预测标签。 管道的输出是机器学习模型,事实上是一种转换器,可用于将模型函数应用于数据帧中的特征并预测相应的标签值。