使用 Python 进行机器学习 - 准备数据


介绍

机器学习算法完全依赖于数据,因为它是使模型训练成为可能的最关键的方面。另一方面,如果我们在将数据输入机器学习算法之前无法理解这些数据,那么机器将毫无用处。简而言之,我们总是需要提供正确的数据,即具有正确规模、格式并包含有意义特征的数据,以解决我们希望机器解决的问题。

这使得数据准备成为机器学习过程中最重要的步骤。数据准备可以定义为使我们的数据集更适合机器学习过程的过程。

为什么要进行数据预处理?

选择机器学习训练的原始数据后,最重要的任务是数据预处理。从广义上讲,数据预处理会将所选数据转换为我们可以使用或可以输入机器学习算法的形式。我们总是需要对数据进行预处理,使其符合机器学习算法的期望。

数据预处理技术

我们有以下数据预处理技术,可以应用于数据集来为 ML 算法生成数据 -

缩放

我们的数据集很可能包含不同比例的属性,但我们无法向 ML 算法提供此类数据,因此需要重新调整比例。数据重新缩放可确保属性处于相同的比例。通常,属性会重新缩放到 0 和 1 的范围内。梯度下降和 k 最近邻等 ML 算法需要缩放数据。我们可以借助 scikit-learn Python 库的 MinMaxScaler 类重新缩放数据。

例子

在此示例中,我们将重新调整之前使用的皮马印第安人糖尿病数据集的数据。首先,将加载 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 的范围内。

正常化

另一种有用的数据预处理技术是标准化。这用于将每行数据的长度重新调整为 1。它主要在有很多零的稀疏数据集中有用。我们可以借助 scikit-learn Python 库的 Normalizer 类来重新缩放数据。

标准化的类型

在机器学习中,有两种类型的归一化预处理技术,如下所示 -

L1 归一化

它可以被定义为一种标准化技术,它以每行中的绝对值之和始终达到 1 的方式修改数据集值。它也称为最小绝对偏差。

例子

在此示例中,我们使用 L1 归一化技术对之前使用的皮马印第安人糖尿病数据集的数据进行归一化。首先,将加载 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. ]
]

L2 归一化

它可以被定义为一种标准化技术,它以每行的平方和始终达到 1 的方式修改数据集值。它也称为最小二乘法。

例子

在此示例中,我们使用 L2 归一化技术对之前使用的皮马印第安人糖尿病数据集的数据进行归一化。首先,将加载 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]
]

二值化

顾名思义,这是我们可以制作数据二进制的技术。我们可以使用二进制阈值来使数据二进制化。高于该阈值的值将转换为 1,低于该阈值的值将转换为 0。例如,如果我们选择阈值 = 0.5,则高于该阈值的数据集值将变为 1,低于该阈值的值将变为 0。即为什么我们可以将其称为数据二值化或数据阈值化。当我们的数据集中有概率并希望将它们转换为清晰的值时,此技术非常有用。

我们可以借助 scikit-learn Python 库的 Binarizer 类对数据进行二值化。

例子

在此示例中,我们将重新调整之前使用的皮马印第安人糖尿病数据集的数据。首先,将加载 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.]
]

标准化

另一种有用的数据预处理技术,基本上用于将数据属性转换为高斯分布。它将平均值和 SD(标准差)与平均值为 0、SD 为 1 的标准高斯分布不同。此技术在 ML 算法中非常有用,例如线性回归、逻辑回归,这些算法假设输入数据集中呈高斯分布并产生更好的结果重新调整数据的结果。我们可以借助 scikit-learn Python 库的 StandardScaler 类来标准化数据(均值 = 0 且 SD =1)。

例子

在此示例中,我们将重新调整之前使用的皮马印第安人糖尿病数据集的数据。首先,将加载 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]
]

数据标签

我们讨论了良好的数据对于 ML 算法的重要性,以及在将数据发送到 ML 算法之前对数据进行预处理的一些技术。这方面的另一个方面是数据标签。将数据发送到具有正确标记的 ML 算法也非常重要。例如,在分类问题中,数据上存在大量单词、数字等形式的标签。

什么是标签编码?

大多数 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']