介绍
欢迎来到 scikit-learn 数据预处理实验。在机器学习中,数据的质量直接影响模型的性能。原始数据通常是混乱的、不一致的,并且不适合算法使用的最佳格式。数据预处理是一个关键步骤,它包括清理和转换数据,使其适用于机器学习模型。
在本实验中,你将学习如何使用 scikit-learn 库执行两项基本预处理任务:
- **特征缩放 (Feature Scaling)**:标准化自变量或数据特征的范围。
- **标签编码 (Label Encoding)**:将分类标签转换为数值格式。
我们将使用著名的 Iris 数据集,该数据集已包含在 scikit-learn 中,方便我们练习这些技术。在本实验结束时,你将对如何为机器学习管道准备数据有扎实的理解。
使用 X = iris.data, y = iris.target 将数据分割为特征和目标
在此步骤中,我们将首先加载 Iris 数据集并将其分割为特征和目标变量。在机器学习中,X 是特征(输入变量)的约定性表示,而 y 是目标(你希望预测的输出变量)的表示。
scikit-learn 库通过其 datasets 模块提供了 Iris 数据集。加载的数据集对象表现得像一个字典。
Iris 数据集结构:
iris.data: 特征矩阵(150 个样本 × 4 个特征)iris.target: 目标标签(150 个样本)iris.feature_names: 4 个特征的名称iris.target_names: 3 种花卉物种的名称
为什么需要分割 X 和 y?
X: 输入特征(模型从中学习的内容)y: 目标标签(模型预测的内容)- 这是机器学习中的标准约定
首先,使用左侧的文件浏览器打开位于 ~/project 目录下的 preprocess.py 文件。我们将把代码添加到此文件中。
在 ## --- Step 1: Split data --- 注释下添加以下行,分别将特征和目标赋值给 X 和 y。我们还将打印它们的形状以进行验证。
## --- Step 1: Split data ---
X = iris.data
y = iris.target
print("Shape of features (X):", X.shape)
print("Shape of target (y):", y.shape)
现在,保存文件并在终端中运行它以查看输出。
python3 preprocess.py
你应该会看到以下输出,这表明我们有 150 个样本和 4 个特征,以及 150 个对应的目标标签。
Shape of features (X): (150, 4)
Shape of target (y): (150,)
使用 sklearn.preprocessing 中的 StandardScaler 进行特征缩放
在此步骤中,我们将准备对特征进行缩放。特征缩放是许多机器学习算法的常见要求,因为它们可能对输入特征的尺度敏感。StandardScaler 是一种流行的技术,它通过移除均值并将特征缩放到单位方差来标准化特征。
StandardScaler 的工作原理:
- 公式:
z = (x - u) / s,其中u是训练样本的均值,s是标准差 - 效果:将数据转换为均值为 0,标准差为 1
- 优势:防止具有较大尺度的特征主导学习过程
StandardScaler 的关键参数:
with_mean=True(默认值):通过移除均值来中心化数据with_std=True(默认值):通过除以标准差来缩放数据
我们将使用 sklearn.preprocessing 中的 StandardScaler。过程的第一部分是创建一个 scaler 的实例。
在你的 preprocess.py 文件中,在 ## --- Step 2: Initialize the scaler --- 注释下添加以下代码,以创建 StandardScaler 的实例。
## --- Step 2: Initialize the scaler ---
scaler = StandardScaler()
print("Scaler object created:", scaler)
再次保存文件并运行它。
python3 preprocess.py
输出现在将包含一行确认 StandardScaler 对象已成功创建。
Shape of features (X): (150, 4)
Shape of target (y): (150,)
Scaler object created: StandardScaler()
使用 scaler.fit(X) 拟合 scaler
在此步骤中,我们将使用特征数据 X 来拟合 StandardScaler。fit() 方法是 scikit-learn 中的一个基本概念。
fit() 的作用:
- 从训练数据中计算必要的统计量(均值和标准差)
- 将这些参数内部存储以供后续使用
- 重要提示:仅从数据中学习,不进行转换
为什么需要区分 fit() 和 transform()?
- 仅在训练数据上拟合:通过仅从训练集中学习参数来防止数据泄露
- 应用于任何数据:可以使用相同的学习参数转换训练数据和测试数据
- 一致性:确保对所有数据应用相同的转换
实际最佳实践:
scaler.fit(X_train)- 仅从训练数据中学习参数X_train_scaled = scaler.transform(X_train)- 转换训练数据X_test_scaled = scaler.transform(X_test)- 使用相同参数转换测试数据
在你的 preprocess.py 文件中,在 ## --- Step 3: Fit the scaler --- 注释下添加以下代码。我们还将打印 scaler 的 mean_ 属性,以查看它学习到了什么。
## --- Step 3: Fit the scaler ---
scaler.fit(X)
print("Scaler mean:", scaler.mean_)
保存文件并执行它。
python3 preprocess.py
输出现在将显示这四个特征的均值,这些均值是 scaler 从数据中计算出来的。
Shape of features (X): (150, 4)
Shape of target (y): (150,)
Scaler object created: StandardScaler()
Scaler mean: [5.84333333 3.05733333 3.758 1.19933333]
使用 scaler.transform(X) 转换数据
在此步骤中,我们将使用已拟合的 scaler 来转换我们的数据。transform() 方法将缩放转换应用于数据,使用在 fit() 步骤中计算的均值和标准差。这将使我们的数据中心化,均值为 0,标准差为 1。
我们将把转换后的数据存储在一个名为 X_scaled 的新变量中,以保持原始数据不变。
理解代码:
X_scaled = scaler.transform(X):将学习到的转换应用于我们的数据np.set_printoptions(precision=2, suppress=True):格式化输出以提高可读性precision=2:显示 2 位小数suppress=True:对非常小/大的数字使用科学计数法
np.mean(X, axis=0):沿轴 0(列)计算均值axis=0:计算所有样本中每个特征(列)的均值- 结果:每个特征一个均值
在你的 preprocess.py 文件中,在 ## --- Step 4: Transform the data --- 注释下添加以下代码。我们将打印原始数据和缩放后数据的均值,以观察转换的效果。
## --- Step 4: Transform the data ---
X_scaled = scaler.transform(X)
## Use numpy to set precision for cleaner output
np.set_printoptions(precision=2, suppress=True)
print("Original data mean:", np.mean(X, axis=0))
print("Scaled data mean:", np.mean(X_scaled, axis=0))
print("Scaled data sample:\n", X_scaled[:5])
保存文件并运行它。
python3 preprocess.py
你将看到缩放后数据的均值实际上为零,并且样本数据值已被转换。
Shape of features (X): (150, 4)
Shape of target (y): (150,)
Scaler object created: StandardScaler()
Scaler mean: [5.84333333 3.05733333 3.758 1.19933333]
Original data mean: [5.84 3.06 3.76 1.2 ]
Scaled data mean: [-0. -0. -0. -0.]
Scaled data sample:
[[-0.9 1.02 -1.34 -1.32]
[-1.14 -0.13 -1.34 -1.32]
[-1.39 0.33 -1.4 -1.32]
[-1.51 0.1 -1.28 -1.32]
[-1.02 1.25 -1.34 -1.32]]
使用 sklearn.preprocessing 的 LabelEncoder 编码分类目标变量
在此步骤中,我们将预处理目标变量 y。Iris 数据集的 target 是分类的,用数字 0、1 和 2 表示,它们对应于三种不同的鸢尾花物种。虽然它们已经是数字格式,但了解如何编码分类标签是一个好习惯,特别是当它们是字符串格式时(例如,'setosa'、'versicolor')。
LabelEncoder 详解:
- 目的:将分类标签(字符串或混合类型)转换为整数
- 工作原理:为每个唯一类别分配一个唯一的整数
- 示例:['cat', 'dog', 'cat'] → [0, 1, 0]
为什么使用 LabelEncoder?
- 许多机器学习算法需要数字输入
- 高效的存储和计算
- 保持数据的分类性质
关键方法:
fit(y):学习从类别到整数的映射transform(y):应用学习到的映射fit_transform(y):在一个调用中组合这两个步骤inverse_transform(y_encoded):将整数转换回原始类别
重要提示:
- 顺序是任意的(基于首次出现或排序)
- 不适用于顺序很重要(ordinal data)的数据(请改用 OrdinalEncoder)
- 对于特征(而非目标),请考虑对名义数据(nominal data)使用 OneHotEncoder
在你的 preprocess.py 文件中,在 ## --- Step 5: Encode the target --- 注释下添加以下代码。我们将创建一个 LabelEncoder 实例并使用 fit_transform() 方法,该方法将拟合和转换合并为一个步骤。
## --- Step 5: Encode the target ---
encoder = LabelEncoder()
y_encoded = encoder.fit_transform(y)
print("\nOriginal target sample:", y[:5]) ## Show first 5 original labels
print("Encoded target sample:", y_encoded[:5]) ## Show first 5 encoded labels
print("Unique encoded values:", np.unique(y_encoded)) ## Show all unique encoded values
保存文件并最后一次运行它。
python3 preprocess.py
输出将显示目标变量已被编码。由于它已经处于正确的整数格式,结果是相同的,但这演示了你将用于基于字符串的标签的过程。
Shape of features (X): (150, 4)
Shape of target (y): (150,)
Scaler object created: StandardScaler()
Scaler mean: [5.84333333 3.05733333 3.758 1.19933333]
Original data mean: [5.84 3.06 3.76 1.2 ]
Scaled data mean: [-0. -0. -0. -0.]
Scaled data sample:
[[-0.9 1.02 -1.34 -1.32]
[-1.14 -0.13 -1.34 -1.32]
[-1.39 0.33 -1.4 -1.32]
[-1.51 0.1 -1.28 -1.32]
[-1.02 1.25 -1.34 -1.32]]
Original target sample: [0 0 0 0 0]
Encoded target sample: [0 0 0 0 0]
Unique encoded values: [0 1 2]
总结
恭喜你完成了本次实验!你已成功使用 scikit-learn 执行了关键的数据预处理任务。
在本次实验中,你学会了如何:
- 从 scikit-learn 加载标准数据集。
- 将数据分离为特征 (
X) 和目标 (y)。 - 使用
StandardScaler对数值特征进行缩放,首先通过fit学习参数,然后transform数据。 - 使用
LabelEncoder将分类目标标签编码为机器可读的整数格式。
这些预处理步骤是构建健壮且高性能机器学习模型的基础。现在你已为未来的机器学习项目准备自己的数据集做好了更充分的准备。



