Machine Learning 简明教程
Data Preparation in Machine Learning
数据准备是机器学习过程中的一个关键步骤,会对最终模型的准确性和有效性产生重大影响。它需要仔细关注细节,并透彻地理解数据和手头的问题。
让我们讨论一下应该如何准备数据以使其与模型相匹配,以提高准确性和结果。
What is Data Preparation?
数据准备是处理原始数据(即清理、组织和转换数据)以使其与机器学习算法保持一致的过程。数据准备是一个持续的过程,并且对机器学习模型的性能有很大影响。干净且结构化的数据将带来更好的结果。
Importance of Data Preparation
在机器学习中,模型从输入的数据中学习。因此,算法只有在数据有条理且完美的情况下才能有效地学习。用于模型的数据的质量会对模型的性能产生重大影响。
定义数据准备在机器学习中重要性的几个方面 −
-
提高模型准确性 − 机器学习算法完全依赖数据。当您向模型提供干净且结构化的数据时,结果是准确的。
-
Facilitates Feature Engineering − 数据准备通常包括选择或创建新特征以训练模型的过程。因此,数据准备将使特征工程变得容易。
-
数据质量 − 收集的数据最常包含不一致、错误和无关的信息。因此,当应用数据清理、转换等任务时,数据会被格式化并整理。这可用于获得见解和模式。
-
启用预测率 − 准备好的数据使分析结果变得更容易,并能产生准确的结果。
Data Preparation Process Steps
数据准备过程涉及一系列步骤,这些步骤对于使数据适合于分析和建模是必需的。数据准备的目标是确保数据对于分析而言是准确、完整和相关的。
以下是数据准备中涉及的一些关键步骤 −
-
Data Collection
-
Data Cleaning
-
Data Transformation
-
Data Reduction
-
Data Splitting
让我们详细了解以上每个步骤 −
Data Collection
数据收集是机器学习流程中的第一步,其中收集来自不同来源的数据来做出决定、回答研究问题以及制定统计规划。数据收集可使用数据库、文本文件、图片、声音文件或网络爬取等不同来源。在选择数据后,必须对数据进行预处理以获得见解。执行此步骤是将数据置于适合解决问题的适当格式。有时候,数据收集紧随数据集成步骤之后。
Data integration 涉及将来自多个来源的数据合并到一个数据集进行分析。这可能涉及匹配或链接跨不同数据集的记录,或基于通用变量合并数据集。
在选取原始数据后,最重要的工作即为 data preprocessing 。广义上,数据预处理将选中的数据转换成一种我们可以处理或可以输入 ML 算法的形式。我们始终需要预处理数据,以便其按照机器学习算法的期望来进行。数据预处理包括数据清理、转换和精简。让我们仔细讨论这三个中的每一个。
Data Cleaning
Data cleaning 是识别和修正数据中的错误、缺失值、重复值、异常值等的流程。此步骤在机器学习流程中很关键,因为它确保了数据准确、相关并且没有错误。
用于数据清理的常见技术包括插补、异常值检测和移除等。以下是数据清理的步骤序列:
1. Handling duplicate values
数据集中存在重复的内容,这可能会由于数据输入错误或收集数据时的问题而发生。用来去除重复项的技术是首先识别出它们,然后使用 drop_duplicates function in Pandas 删除它们。
3. Dealing outliers
异常值是与数据不同寻常且有很大差异的值。用于检测异常值的技术包括 z-score 或 IQR method 等统计方法以及 clustering 和 SVM’s 等机器学习方法。
Data Transformation
Data transformation 是将数据从原始格式转换为适合分析和建模的格式的过程。这可能包括定义结构、对齐数据、从源中提取数据,然后以适当形式存储它。
有许多可用来将数据转换成合适格式的技术。一些常用的 data transformation techniques 如下:
-
Scaling
-
标准化——L1 和 L2 标准化
-
Standardization
-
Binarization
-
Encoding
-
Log Transformation
让我们详细讨论以上每一种数据转换技术:
1. Scaling
大多数情况下,我们收集的数据包含不同规模的属性,但是我们不能向 ML 算法提供此类数据,因此需要重新缩放。 Data scaling 确保了属性具有相同的规模,即范围通常为 0 到 1。
我们可以借助 scikit-learn Python 库的 MinMaxScaler 类重新缩放数据。
在这个示例中,我们将重新缩放我们之前使用的 Pima Indians Diabetes 数据集的数据。首先,将加载 CSV 数据(如前几章中所做的那样),然后借助 MinMaxScaler 类,将数据重新缩放至 0 和 1 之间的范围。
以下脚本的前几行与我们在加载 CSV 数据时在之前的章节中写的一样。
from pandas import read_csv
from numpy import set_printoptions
from sklearn import preprocessing
path = r'C:\pima-indians-diabetes.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(path, names=names)
array = dataframe.values
现在,我们可以使用 MinMaxScaler 类将数据重新缩放到 0 和 1 的范围内。
data_scaler = preprocessing.MinMaxScaler(feature_range=(0,1))
data_rescaled = data_scaler.fit_transform(array)
我们还可以根据自己的选择总结数据以供输出。在这里,我们将精度设置为 1,并在输出中显示前 10 行。
set_printoptions(precision=1)
print ("\nScaled data:\n", data_rescaled[0:10])
Scaled data:
[
[0.4 0.7 0.6 0.4 0. 0.5 0.2 0.5 1. ]
[0.1 0.4 0.5 0.3 0. 0.4 0.1 0.2 0. ]
[0.5 0.9 0.5 0. 0. 0.3 0.3 0.2 1. ]
[0.1 0.4 0.5 0.2 0.1 0.4 0. 0. 0. ]
[0. 0.7 0.3 0.4 0.2 0.6 0.9 0.2 1. ]
[0.3 0.6 0.6 0. 0. 0.4 0.1 0.2 0. ]
[0.2 0.4 0.4 0.3 0.1 0.5 0.1 0.1 1. ]
[0.6 0.6 0. 0. 0. 0.5 0. 0.1 0. ]
[0.1 1. 0.6 0.5 0.6 0.5 0. 0.5 1. ]
[0.5 0.6 0.8 0. 0. 0. 0.1 0.6 1. ]
]
从上述输出中,所有数据都重新缩放到 0 和 1 的范围内。
2. Normalization
归一化用于将数据重新缩放到 0 和 1 之间的分布值。对于每个特征,最小值被设置为 0,最大值被设置为 1。
这用于将数据的每一行重新缩放到长度为 1。这主要用于我们有很多零值的稀疏数据集。我们可以在 scikit-learn Python 库的 Normalizer 类的帮助下重新缩放到数据。
在机器学习中,有 two types 归一化预处理技术如下 −
它可以定义为一种归一化技术,它以一种方式修改数据集值,使得每一行的绝对值之和始终高达 1。它也称为最小绝对偏差。
在此示例中,我们使用 L1 归一化技术来归一化我们先前使用的 Pima Indians 糖尿病数据集的数据。首先,将加载 CSV 数据,然后在 Normalizer 类的帮助下对其进行归一化。
以下脚本的前几行与我们在加载 CSV 数据时在之前的章节中写的一样。
from pandas import read_csv
from numpy import set_printoptions
from sklearn.preprocessing import Normalizer
path = r'C:\pima-indians-diabetes.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv (path, names=names)
array = dataframe.values
现在,我们可以使用 L1 的 Normalizer 类来对数据进行归一化。
Data_normalizer = Normalizer(norm='l1').fit(array)
Data_normalized = Data_normalizer.transform(array)
我们还可以根据自己的选择总结数据以供输出。在这里,我们将精度设置为 2,并在输出中显示前 3 行。
set_printoptions(precision=2)
print ("\nNormalized data:\n", Data_normalized [0:3])
Normalized data:
[
[0.02 0.43 0.21 0.1 0. 0.1 0. 0.14 0. ]
[0. 0.36 0.28 0.12 0. 0.11 0. 0.13 0. ]
[0.03 0.59 0.21 0. 0. 0.07 0. 0.1 0. ]
]
它可以定义为一种归一化技术,它以一种方式修改数据集值,使得每一行的平方和始终高达 1。它也称为最小二乘。
在此示例中,我们使用 L2 归一化技术来归一化我们先前使用的 Pima Indians 糖尿病数据集的数据。首先,将加载 CSV 数据(如前几章中所述),然后在 Normalizer 类的帮助下对其进行归一化。
以下脚本的前几行与我们在加载 CSV 数据时在之前的章节中写的一样。
from pandas import read_csv
from numpy import set_printoptions
from sklearn.preprocessing import Normalizer
path = r'C:\pima-indians-diabetes.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv (path, names=names)
array = dataframe.values
现在,我们可以使用 L1 的 Normalizer 类来对数据进行归一化。
Data_normalizer = Normalizer(norm='l2').fit(array)
Data_normalized = Data_normalizer.transform(array)
我们还可以根据自己的选择总结数据以供输出。在这里,我们将精度设置为 2,并在输出中显示前 3 行。
set_printoptions(precision=2)
print ("\nNormalized data:\n", Data_normalized [0:3])
Normalized data:
[
[0.03 0.83 0.4 0.2 0. 0.19 0. 0.28 0.01]
[0.01 0.72 0.56 0.24 0. 0.22 0. 0.26 0. ]
[0.04 0.92 0.32 0. 0. 0.12 0. 0.16 0.01]
]
3. Standardization
标准化用于将数据属性转换为标准高斯分布,均值为 0,标准差为 1。这种技术在诸如线性回归、逻辑回归等 ML 算法中非常有用,它假设输入数据集是高斯分布的,并且使用重新缩放到数据产生更好的结果。
我们可以在 scikit-learn Python 库的 StandardScaler 类的帮助下对数据进行标准化(均值 = 0 且 SD =1)。
在此示例中,我们将重新调整先前使用的 Pima Indians 糖尿病数据集的数据。首先,将加载 CSV 数据,然后在 StandardScaler 类的帮助下,将其转换为均值 = 0 和 SD = 1 的高斯分布。
以下脚本的前几行与我们在加载 CSV 数据时在之前的章节中写的一样。
from sklearn.preprocessing import StandardScaler
from pandas import read_csv
from numpy import set_printoptions
path = r'C:\pima-indians-diabetes.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(path, names=names)
array = dataframe.values
现在,我们可以使用 StandardScaler 类来重新缩放到数据。
data_scaler = StandardScaler().fit(array)
data_rescaled = data_scaler.transform(array)
我们还可以根据自己的选择总结数据以供输出。在这里,我们将精度设置为 2,并在输出中显示前 5 行。
set_printoptions(precision=2)
print ("\nRescaled data:\n", data_rescaled [0:5])
Rescaled data:
[
[ 0.64 0.85 0.15 0.91 -0.69 0.2 0.47 1.43 1.37]
[-0.84 -1.12 -0.16 0.53 -0.69 -0.68 -0.37 -0.19 -0.73]
[ 1.23 1.94 -0.26 -1.29 -0.69 -1.1 0.6 -0.11 1.37]
[-0.84 -1. -0.16 0.15 0.12 -0.49 -0.92 -1.04 -0.73]
[-1.14 0.5 -1.5 0.91 0.77 1.41 5.48 -0.02 1.37]
]
4. Binarization
顾名思义,这是一个可以帮助我们使数据实现二进制化的技术。我们可以使用二进制阈值使数据实现二进制化。高于该阈值的值将转换为 1,低于该阈值的值将转换为 0。例如,如果我们选择阈值 = 0.5,则数据集值高于该值将变为 1,低于则变为 0。这就是为什么我们可以称之为 binarizing 数据或 thresholding 数据。当我们数据集中有概率并希望将它们转换为固定值时,这个技术很有用。
我们可以借助 scikit-learn Python 库中的 Binarizer 类对数据进行二值化。
在这个示例中,我们将重新调整前面使用过的 Pima Indians Diabetes 数据集的数据。首先,将加载 CSV 数据,然后借助 Binarizer 类,根据阈值将其转换为二进制值,即 0 和 1。我们选择 0.5 作为阈值。
以下脚本的前几行与我们在加载 CSV 数据时在之前的章节中写的一样。
from pandas import read_csv
from sklearn.preprocessing import Binarizer
path = r'C:\pima-indians-diabetes.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = read_csv(path, names=names)
array = dataframe.values
现在,我们可以使用 Binarize 类将该数据转换为二进制值。
binarizer = Binarizer(threshold=0.5).fit(array)
Data_binarized = binarizer.transform(array)
在此处,我们显示输出中的前 5 行。
print ("\nBinary data:\n", Data_binarized [0:5])
Binary data:
[
[1. 1. 1. 1. 0. 1. 1. 1. 1.]
[1. 1. 1. 1. 0. 1. 0. 1. 0.]
[1. 1. 1. 0. 0. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 0. 1. 0.]
[0. 1. 1. 1. 1. 1. 1. 1. 1.]
]
5. Encoding
此技术用于将分类变量转换为数值表达。一些常见的编码技术包括 one-hot encoding 、 label encoding 和 target encoding 。
大多数 sklearn 函数都需要的是以数字标记表示的数据,而不是以单词标记的数据。因此,我们需要将此类标记转换为数字标记。此过程称为标记编码。我们可以借助 scikit-learn Python 库的 LabelEncoder() 函数对数据执行标记编码。
在以下示例中,Python 脚本将执行标记编码。
首先,按如下方式导入所需的 Python 库 −
import numpy as np
from sklearn import preprocessing
现在,我们需要提供输入标记,如下所示 −
input_labels = ['red','black','red','green','black','yellow','white']
代码的下一行将创建标记编码器并对其进行训练。
encoder = preprocessing.LabelEncoder()
encoder.fit(input_labels)
脚本的下一行将通过对随机有序的列表进行编码来检查性能 −
test_labels = ['green','red','black']
encoded_values = encoder.transform(test_labels)
print("\nLabels =", test_labels)
print("Encoded values =", list(encoded_values))
encoded_values = [3,0,4,1]
decoded_list = encoder.inverse_transform(encoded_values)
我们可以借助以下 python 脚本获取编码值列表 −
print("\nEncoded values =", encoded_values)
print("\nDecoded labels =", list(decoded_list))
Labels = ['green', 'red', 'black']
Encoded values = [1, 2, 0]
Encoded values = [3, 0, 4, 1]
Decoded labels = ['white', 'black', 'yellow', 'green']
Data Reduction
数据减少是一种通过选择与分析最相关的特征或观察子集来减小数据集大小的技术。这有助于减少噪声并提高模型的准确性。
当数据集非常大或者数据集包含大量不相关数据时,此方法非常有用。
应用的最常见技术之一是 Dimensionality Reduction ,它可以在不丢失重要信息的情况下减小数据集的大小。另一个方法是 Discretization ,其中时间和温度等连续值将转换为离散的类别,从而简化了数据。
Data Splitting
Data Splitting 是为机器学习准备数据的最后一步,其中将数据拆分到不同的集合中 -
-
Training − 由机器学习模型用于学习模式的子集。
-
Validation − 训练时用于评估机器学习模型性能的子集。
-
Testing − 用于评估训练模型的性能和效率的子集。
Python Example
我们看一个使用乳腺癌数据集进行数据准备的示例:
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# load the dataset
data = load_breast_cancer()
# separate the features and target
X = data.data
y = data.target
# split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# normalize the data using StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
在此示例中,我们首先使用 scikit-learn 中的 load_breast_cancer 函数加载乳腺癌数据集。然后我们分离特征和目标,并使用 train_test_split 函数将数据分成训练集和测试集。
最后,我们对数据进行标准化,使用 scikit-learn 中的 StandardScaler,它会减去均值并将数据扩展到单位方差。这有助于将所有特征都调整到相似的范围,这对于 SVM 和神经网络等模型尤其重要。