准备机器学习的数据:处理缺失值、编码和平衡
目录
回顾:独热编码基础
在我们之前的课程中,我们介绍了独热编码——一种将分类变量转换为适合机器学习算法格式的方法。我们添加了必要的语句,但暂停以探索更多变量和内容。今天,我们将在此基础上进行扩展。
处理缺失值
识别缺失数据
在编码之前,确保您的数据集中没有缺失值至关重要,因为缺失值可能导致模型训练期间出现错误。使用 pandas,我们可以通过以下方法识别缺失值:
1 2 3 4 |
import pandas as pd missing_values = pd.isnull(x).sum() print(missing_values) |
总和为零表示没有缺失值。然而,如果某些列显示非零值,则这些列包含需要处理的缺失数据。
管理数值和分类缺失数据
我们已经成功使用均值或中位数插补等策略处理了数值列中的缺失值。然而,分类(字符串)列需要不同的方法。对于分类数据,通常使用最频繁的值进行插补。以下是实现方法:
1 2 3 4 5 6 7 8 9 |
from sklearn.impute import SimpleImputer # 对于数值数据 num_imputer = SimpleImputer(strategy='mean') x_numeric = num_imputer.fit_transform(x_numeric) # 对于分类数据 cat_imputer = SimpleImputer(strategy='most_frequent') x_categorical = cat_imputer.fit_transform(x_categorical) |
处理日期特征
日期可能会比较棘手,因为它们通常包含唯一值,使其对预测建模的作用较小。包含整个日期可能会引入高维度,减慢模型速度而不增加预测能力。以下是一些策略:
- 特征提取:提取有意义的组成部分,如日和月,同时舍弃年份。
- 标签编码:为日期分配数值标签,但要小心,因为这可能引入意外的序数关系。
- 独热编码:由于特征数量爆炸,不推荐用于日期。
鉴于这些挑战,如果日期特征对您的模型并非必不可少,最直接的解决方案是完全删除日期特征:
1 |
x = x.drop(['date'], axis=1) |
在我们的案例中,根据 Kaggle 的“澳大利亚降雨预测”数据集描述,我们还排除了 risk_mm
变量以获得更好的性能。
独热编码重温
在处理缺失值和删除不相关特征后,我们继续进行独热编码:
1 2 3 4 5 |
from sklearn.preprocessing import OneHotEncoder encoder = OneHotEncoder() x_encoded = encoder.fit_transform(x) print(x_encoded.shape) # 示例输出:(样本数量, 115) |
如预期所示,由于编码过程,列数增加了,从我们的示例中的23增加到115。
处理不平衡数据
不平衡的数据集可能会使您的模型偏向多数类,降低其准确预测少数类的能力。以下是解决方法:
- 检查不平衡:
1234from collections import Countercounter = Counter(y)print(counter) # 示例输出:{0: 2700, 1: 900}
如果一个类别显著多于另一个类别(例如,75% 对 25%),则需要进行平衡处理。
- 对少数类进行上采样:
123456789101112131415161718192021from sklearn.utils import resample# 合并为一个 DataFramedata = pd.concat([x_encoded, y], axis=1)# 分离多数类和少数类majority = data[data.y == 0]minority = data[data.y == 1]# 对少数类进行上采样minority_upsampled = resample(minority,replace=True,n_samples=len(majority),random_state=42)# 将多数类与上采样后的少数类合并balanced_data = pd.concat([majority, minority_upsampled])# 分离特征和目标X_balanced = balanced_data.drop('y', axis=1)y_balanced = balanced_data['y']
- 验证:
12print(Counter(y_balanced))# 输出: {0: 2700, 1: 2700}
拆分数据
在平衡数据后,我们继续将其拆分为训练集和测试集:
1 2 3 4 5 |
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X_balanced, y_balanced, test_size=0.2, random_state=42) |
特征缩放
最后,我们对特征进行标准化,以确保每个特征对模型性能的贡献相等:
1 2 3 4 5 6 7 8 |
from sklearn.preprocessing import StandardScaler scaler = StandardScaler(with_mean=False) # 避免对稀疏矩阵进行居中 X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) print(X_train_scaled.shape) print(X_test_scaled.shape) |
注意:在处理由独热编码生成的稀疏矩阵时,在 StandardScaler
中设置 with_mean=False
可防止与居中相关的错误。
结论
数据预处理既是一门艺术也是一门科学,需要深思熟虑的决策以有效地准备您的数据集。通过处理缺失值、编码分类变量、管理日期特征和平衡数据,您为构建稳健的机器学习模型奠定了坚实的基础。请记住,数据的质量直接影响模型的性能,因此在这些预处理步骤中投入必要的时间和精力。
欢迎随时回顾这个 Jupyter 笔记本以获得实操体验,如有任何问题,请随时联系。祝您建模愉快!