数据特征预处理
一、什么是特征预处理
我们在进行特征抽取后,需要根据算法的要求,使用特定的统计方法(数学方法)将数据转换成其所需格式。对于不同的数据类型有不同的转换方法。
1、数值类型数据
对于数值类型数据可采用标准的缩放,其方法有:
- 归一化
- 标准化
- 缺失值处理
2、类别型数据
采用one-hot编码,像字典、文本数据进行特征抽取,转成了one-hot编码。
3、时间类型
采用时间切分的方式。
注意:这里主要说说数值型数据的预处理方式。
二、数值类型处理
(一)归一化
1、为什么使用归一化
归一化是将数据样本缩放到[0,1]的区间范围,那么为什么要这样做呢?因为在特征(维度)非常多的时候,避免某一维或者某几维对数据的影响过大,同时也是为了把不同来源的数据同一到一个度量标准下,这样比较起来才有意义。
样本 |
身高(cm) |
体重(kg) |
样本一 |
150 |
50 |
样本二 |
200 |
70 |
假设现在有这样的样本数据,k-近邻算法中一个距离公式是这样的:
(200-150)^2 + (70-50)^2
如果两个人的体型差异较大,以至于第一个身高差的平方的值打到忽略体重差平方的值,这样是不是体重这个特征就会被忽略了。所以为了解决这个问题,我们需要将数据进行归一化。
2、归一化的原理
归一化的特点:通过对原始数据进行变换把数据映射到(默认为[0,1])之间
公式: 𝑋′= (𝑥−𝑚𝑖𝑛)/(𝑚𝑎𝑥−𝑚𝑖𝑛) 𝑋′′=𝑋′∗(𝑚𝑥−𝑚𝑖)+𝑚𝑖
注意:作用于每一列,max为每一列的最大值,min为每一列的最小值,X''为最终结果,mx,mi分别为指定区间值默认最大值(mx=1)、最小值(mi=0)。
对于上述样本进行归一化处理后就是这样:
样本 |
身高(cm) |
体重(kg) |
样本一 |
0 |
0 |
样本二 |
1 |
1 |
计算过程就是利用上述的计算公式,比如样本一的身高进行归一化:
𝑋′=(150-150)/(170-150) = 0 𝑋''=0*(1-0)+0 = 0
3、sklearn进行归一化
- API
sklearn.preprocessing.MinMaxScaler
- 方法及参数
MinMaxScalar(feature_range=(0,1)…)
"""
每个特征缩放到给定范围(默认[0,1])
"""
MinMaxScalar.fit_transform(X)
"""
X:numpy array格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array
"""
- 使用步骤
""" 1、实例化MinMaxScalar 2、通过fit_transform进行转换 """
4、实例演示
from sklearn.preprocessing import MinMaxScaler def mms(): #准备二维的numpy数组 arr = [ [150,50], [200,70] ] #实例化MinMaxScaler mms = MinMaxScaler() #可以传入feature_range=(mi, mx)指定缩放的范围 #调用fit_transform data = mms.fit_transform(arr) print(data) """ [[0. 0.] [1. 1.]] """ if __name__ == '__main__': mms()
5、总结
假如数据中的异常点比较多,会有什么影响呢?它对最大和最小值得影响会比较大,比如由于测量失误导致量了一个体重40多kg的,这样是不是体重的最小值就变成这个测量失误的异常数据了。
所以,最大值与最小值非常容易受异常点影响,这种方法鲁棒性(稳定性)较差,只适合传统精确小数据场景。
(二)标准化
我们知道归一化对于异常数据是无法进行更好的处理的,所以为了解决这个问题,引入标准化。
1、特点
通过对原始数据进行变换把数据变换到均值为0,方差为1范围内。
2、原理
公式:𝑋′= (𝑥−mean)/𝜎
注意:作用于每一列,mean为平均值,𝜎为标准差(考量数据的稳定性)。
std = [(x1-mean)2+(x2-mean)2+...]/n,其中std是方差,n是每个特征的样本数,𝜎=std½
3、标准化与归一化比较
从上面原理的计算公式看,𝑋′的值与平均值和标准差有关,那么如果出现异常点的化,在具有一定数据量的前提下,少量的异常点对于平均值的影响并不大,从而方差的改变量较小。
而从归一化的角度看,异常点影响的是最大值和最小值,对于结果的影响较大。
4、sklearn进行标准化
这里我们直接使用sklearn中的API对数据进行标准化:
scikit-learn.preprocessing.StandardScaler
通过StandardScaler方法处理之后样本每列数据都聚集在均值为0附近,方差为1。
- StandardScaler.fit_transform(X,y)
X:numpy array格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array
- StandardScaler.mean_
原始数据中每列特征的平均值
from sklearn.preprocessing import StandardScaler def ss(): """ 标准化处理 :return: """ #准备数据 arr = [ [150,50], [200,70] ] #实例化StandardScaler ss = StandardScaler() data = ss.fit_transform(arr) print(data) """ [[-1. -1.] [ 1. 1.]] """ print(ss.mean_) """ [175. 60.] """ if __name__ == '__main__': ss()
标准化适用于在嘈杂的大数据场景下,在样本数据足够大的情况下比较稳定。
(三)缺失值处理
1、处理原则
- 删除
如果每列或者每行数据缺失值达到一定的比例,建议放弃整行或者整列
- 插补
通过缺失值每行或者每列的平均值、中位数来填充
2、sklearn缺失值API
sklearn.preprocessing.Imputer
通过Imputer(missing_values='NaN', strategy='mean', axis=0)方法进行缺失值插补。
- Imputer.fit_transform(X,y)
X:numpy array格式的数据[n_samples,n_features] 返回值:转换后的形状相同的array
3、Imputer使用步骤
- 实例化Imputer
指定Imputer参数,包括缺失值(missing_values)、填补策略(strategy)、行或列(axis),其中注意的是缺失值也可以是别的指定要替换的值。
- 调用fit_transform
from sklearn.preprocessing import Imputer import numpy as np def im(): """ 缺失值填补 :return: """ #数据准备 arr = [ [100, 70], [np.nan,50], [200,70] ] # im = Imputer(missing_values="NaN",strategy="mean",axis=0) data = im.fit_transform(arr) print(data) """ [[100. 70.] [150. 50.] [200. 70.]] """ if __name__ == '__main__': im()
注意的:
- 上面指定的axis是列的平均值填充,每一列都是一个特征,所以这样误差会小一些。
- numpy的数组中可以使用np.nan/np.NaN来代替缺失值,属于float类型
- 如果是文件中的一些缺失值,可以替换成nan,通过np.array转化成float型的数组即可