Advertisement

特征数据清洗 编码 标准化

阅读量:

特征工程是机器学习的重要基础步骤之一,在这个过程中主要涉及了对现有数据集进行清洗、优化以及降维等技术操作,并且能够有效提升信号与噪声的比例。在实际应用中发现很多算法对于输入数据做了严格的假设,在处理原始数据集时可能会导致性能上的下降或不稳定现象出现

此外,在某些情况下不同特征之间存在高度的相关性。当其中一个特定的特征能够提供足够的信息时,与之相关的其他特性通常不会带来额外的信息量。此时我们需要研究如何减少数据中的冗余数据或者仅保留最重要的指标。

scikit-learn内置了若干预设的数据集,在sklearn.datasets模块内可供使用。这些数据集一般都包括输入特征集合X以及对应的目标变量y。例如,在回归任务中使用的波斯顿房价数据集:

from sklearn.datasets import load_boston

boston = load_boston()
X = boston.data
y = boston.target

输出内容

详细说明

如果我们不希望依赖于scikit-learn预装的数据集,则可以选择另一种方法来自行生成特定的数据集。这些方法包括:

make_classification():用于创建适用于测试分类算法的数据集;
make_regression():用于创建适用于测试回归模型的数据集;
make_blobs():用于创建适用于测试聚类算法的数据集。
二、创建训练集和测试集
一般来说,我们要在正式应用我们训练的模型前对它进行测试。因此我们需要将数据集分为训练集和测试集,顾名思义,前者用于训练模型参数,后者用于测试模型性能。在某些情况下,我们甚至还会再分出一个数据集作为交叉验证集,这种处理方式适用于有多种模型可供选择的情况。

数据集的分割需注意以下几点:第一,在进行数据集划分时应确保两个子数据集能够充分反映原始数据的整体分布特征;否则在模型训练过程中可能出现偏差导致预测效果不佳;第二,在进行数据集分割之前必须对原始数据进行随机打乱混洗处理;这样可以有效防止同一属性或特征值相邻排列导致的数据间存在潜在的相关性从而影响模型的学习效果

通过在scikit-learn库中应用 train_test_split 函数模块, 我们可以轻松地完成数据集的划分

from sklearn.model_selection import train_test_split

以下是代码中的关键部分:X\_train, X\_test, y\_train, y\_test = train_test_split(X, y, test_size=0.25, random\_state=100)
其中前两个位置参数分别对应特征变量和目标变量;test\_size用于确定测试数据所占的比例;而random\_state则被设定为1以确保结果的一致性

第三章 管理分类数据 在众多分类问题中, 目标数据集包含不同种类的类别标签. 但是, 许多算法无法处理这种数据格式, 因此我们需要对其进行必要的编码处理.

假设我们有一个由10个样本组成的数据集,每个样本有两个特征。

import numpy as np

X = np.random.uniform(0.0, 1.0, size=(10, 2))
y = np.random.choice((‘Male’, ‘Female’), size=(10))

打印出X的数据如下所示:
[[[数值], [数值]], [[数值], [数值]], ..., [[数值], [数值]]]
打印出对应的标签如下:
['类别', '类别', ..., '类别']

  1. 使用LabelEncoder类
    from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
yt = le.fit_transform(y)

print(y)
print(yt)
print(le.classes_)
[‘Female’ ‘Female’ ‘Male’ ‘Female’ ‘Female’ ‘Female’ ‘Male’ ‘Male’
‘Female’ ‘Male’]
[0 0 1 0 0 0 1 1 0 1]
[‘Female’ ‘Male’]
获得逆变换的方法很简单:

此方法显得相对简单易懂。
然而存在一定的局限性:所有的标签都被转换为数值形式。
当采用基于真实值的距离度量时,
其分类器可能会将数值相近的对象归入同一类别。
这种做法可能忽略了每个数值所代表的具体类别信息。
因此我们倾向于采用独热编码(one-hot encoding)的方式,
将数据转换为二进制形式处理。

通过LabelBinarizer工具进行编码

lb = LabelBinarizer()
yb = lb.fit_transform(y)

Print the value of y or display its contents. Similarly, output the values of yb. To obtain the inverse transformation, execute print(lb.inverse_transform(yb)). Observations: The dataset consists of two classes labeled as 'Female' and 'Male'. The first class contains 6 instances, while the second class has 4 instances. The corresponding binary vectors for these labels are provided in the subsequent list. Each vector represents a unique observation with binary encoding for classification purposes. Using LabelBinarizer ensures that we can perform inverse transformations efficiently to retrieve original labels from encoded vectors. This approach allows us to map numerical outputs back to their original categorical representations seamlessly.

在存在多个标签的情况下(也就是),该方法会将其中一个标签标记为1(其余的则标记为0)。这可能引发的问题不容忽视;即我们把多分类问题简化为了二分类问题。

我们可能遇到数据缺失的问题,并提供以下可供选择的解决方案包括:

删除整行数据:这个选项较为激进,在数据集规模较大、缺失特征数量众多且预测风险较高的情况下才会考虑;
创建子模型用于预测这些缺失特征值:第二个方案实施起来较为复杂,因为它需要确定一个有效的监督学习策略来训练每个特征的具体模型,并最终综合它们的预测结果;
采用自动化的方法利用已知数据填补缺失的信息:综合权衡后发现上述两种方法均存在不足之处,在此情况下建议优先选择第三种方案。
from sklearn.preprocessing import Imputer

data = np.array([[1, np.nan, 2],
[2, 3, np.nan],
[-1, 4, 2]])

插入均值

imp = Imputer(strategy=‘mean’)
print(‘Mean:\n’, imp.fit_transform(data))

插入中位数

imp = Imputer(strategy=‘median’)
print(‘Median:\n’, imp.fit_transform(data))

插入众数

初始化一个Imputer对象并设置最频繁策略。
打印结果:Mode
观察输出结果:
Mean矩阵:
[[1,3,5],[6,7,8],[9,10,1]]显示了数据集的均值分布。
Median矩阵:
[[4,5,6],[7,8,9],[10,11,4]]展示了中间值的变化情况。
Mode矩阵:
[[a,b,c],[d,e,f],[g,h,i]]则显示了各特征出现次数最多的值。
通常情况下,
数据集中的特征可以从多样的分布中提取,
并且具有各自独特的尺度范围,
偶尔会出现异常值。
当不同特征之间的数值范围差距较大时,
这种差异可能导致模型性能下降,
因此我们常常会对数据进行标准化处理。

我们来对比一下原始数据集和经过缩放和中心化的数据集:

引入标准化工具包StandardScaler。
从sklearn的数据集中导入load_iris。
引入Seaborn库,并以sns为其别名。
引入Python绘图库Matplotlib,并以plt为其别名。
设置Seaborn的默认样式。

导入数据

iris = load_iris()
data = iris.data

绘制原始数据散点图

fig, axes = plt.subplots(1, 2, figsize=(10, 5))
sns.scatterplot(x=data[:, 0], y=data[:, 1], ax=axes[0])

数据归一化

scaler = StandardScaler()
scaled_data = scaler.fit_transform(data)

绘制规范化数据散点图

sns.scatterplot基于标准化后的数据的第一主成分作为x轴,并以标准化后的数据的第二主成分作为y轴,在axes[1]子图中绘制散点图;通过plt.setp函数分别设定各个子图的x轴范围为[-2,8]和y轴范围为[-3,5]

能够观察到的是我们的数据分布形态保持不变然而其覆盖的数据范围确实发生了变化值得注意的是我们对原始数据进行了标准化处理将其转换为均值接近于零(近似等于零)标准差接近于一的标准归一化形式

在数据标准化过程中(即data standardization),我们还可以采用RobustScaler类来控制异常值并设定分位数范围。

from sklearn.preprocessing import RobustScaler

转化数据1

rb1 = RobustScaler(quantile_range=(15, 85))
scaled_data1 = rb1.fit_transform(data)

转化数据2

rb2 = RobustScaler(quantile_range=(25, 75))
scaled_data2 = rb2.fit_transform(data)

转化数据3

rb3 = RobustScaler(quantile_range=(30, 60))
scaled_data3 = rb3.fit_transform(data)

绘制散点图

创建一个名为fig的对象和包含四个子图的axes布局
使用plt.subplots函数生成一个二维网格布局
设置整个图表区域尺寸为宽度10英寸和高度10英寸
在第一个子图(位于第一行第一列)中绘制原始数据集的数据点
在第二个子图(位于第一行第二列)中绘制经过第一个缩放的数据点
在第三个子图(位于第二行第一列)中绘制经过第二个缩放的数据点
在第四个子图(位于第二行第二列)中绘制经过第三个缩放的数据点
调整所有子图中的x轴范围从-2到8,并将y轴范围从-4到5以统一视窗比例

观察到数据的大致分布形态仍然保持相对接近的状态然而其覆盖的数值范围却发生了显著的变化此外采用不同的分位数区间设置也会导致样本数量出现一定的差异

常用的还有Min-Max Scaler与Max Absolute Scaler(也被称作归一化),其中Min-Max Scaler通过移除超出指定范围的数据点来实现特征缩放;而Max Absolute Scaler则基于最大绝对值进行数据缩放

scikit-learn还为每个样本提供了一个归一化处理的类:Normalizer。该类能够将它们应用于Max、L1和L2范数计算中。

Max: 每一个数值都被该数据集的最大数值标准化;
L1: 每一个数值都被该数据集中所有数值绝对值之和标准化;
L2: 每一个数值都被该数据集中所有数值平方后总和开方后的结果标准化;
我们来看一个例子。

from sklearn.preprocessing import Normalizer

生成数据

data = np.array([1, 2]).reshape(1, 2)
print(‘原始数据:’, data)

Max

n_max = Normalizer(norm=‘max’)
print(‘Max:’, n_max.fit_transform(data))

L1范数

n_l1 = Normalizer(norm=‘l1’)
print(‘L1范数:’, n_l1.fit_transform(data))

L2范数

n_l2 = L2归一化器(norm='l2')
print("计算L2范数:", n_l2.fit_transform(data))
原始数据为[[1, 2]]
最大值为[[0.5, 1.0]]
L1范数为[[0.333333, 0.666667]]
L2范数为[[0.447214, 0.894427]]
六、特征选择与过滤
并非所有的特征都能充分提供必要的信息,并且某些特定的特征可能会对模型训练带来负面影响。因此,在开始模型训练之前有必要对特征进行筛选与优化处理。

接下来我们使用SelectKBest方法结合F检验来筛选回归模型的特征。

该模块用于从特征选择中选择最佳特征,并包含回归统计的计算。
获取波士顿房价的数据集。

boston = load_boston()
print('Boston data shape: ', boston.data.shape)

通过SelectKBest模型进行特征选择。
经过SelectKBest模型的转换后得到的新特征集X_new。
打印过滤后的Boston数据形状:

输出内容

from sklearn.feature_selection import SelectPercentile, chi2
from sklearn.datasets import load_iris

iris = load_iris()
print('Boston data shape: ', iris.data.shape)

基于卡方统计量的选择百分位数特征选择器用来提取重要特征. 通过训练选定特征选择器来生成新的特征集. 打印过滤后的波士顿数据形状:, 然后输出新特征集的形状信息.

打印出F分数及其对应特征的重要性。查看原始数据集的维度为(150,4),过滤后的数据维度缩减至(150,1)。F分数分别为[ 10.82,3.59,116.17,67.24]这些数值反映了各特征的重要性程度。在数据预处理阶段中,默认情况下我们会运用主成分分析等技术来实现降维的目标;这一部分内容建议单独作为一章深入讲解;如对相关内容感兴趣的朋友,请持续关注我们的更新内容。

https://zhuanlan.zhihu.com/p/53938233

全部评论 (0)

还没有任何评论哟~