sklearn——数据数据预处理

假装没事ソ 提交于 2021-02-03 06:34:45

一、数据的标准化、归一化、正则化

 

1、标准化

  将数据转化为均值为0方差为1的数据,即标准正态分布。标准化可以规范数据,但不适用于稀疏数据,因为会破坏其数据结果。标准化的过程为两步:去均值的中心化(均值变为0);方差的规模化(方差变为1)。即每一列减去该列的均值再除以该列的方差。

  在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,StandardScaler表现更好。

 

对应函数:

  sklearn.preprocessing.scale(X, axis=0, with_mean=True, with_std=True, copy=True)

  • x:需要标准化标准化的数据。
  • axis:需要标准化的方向,0为列,1为行。
  • with_mean:是否去均值的中心化,默认为True。
  • with_std:是否方差规模化,默认为True。
  • copy:是否要copy数据。

 

代码示例:  

import numpy as np
from sklearn.preprocessing import scale

a=np.random.normal(4,5,[5,2])  #创造数据
a_s=scale(a)    #标准化
print('a:\n',a)
print('\na_s:\n',a_s)
print('\na_s的均值:',a_s.mean(axis=0))
print('\na_s的方差:',a_s.std(axis=0))

'''
结果:
a:
 [[ 3.89399029  5.72996121]
 [ 7.38088249  9.73803222]
 [ 5.8379103  -5.40880669]
 [ 3.29479806 -7.79727102]
 [-0.68205516 -5.71899267]]

a_s:
 [[-0.01873374  0.91171731]
 [ 1.25922106  1.48078964]
 [ 0.69371785 -0.66978276]
 [-0.23833921 -1.00890074]
 [-1.69586596 -0.71382346]]
 
a_s的均值: [-6.66133815e-17  0.00000000e+00]

a_s的方差: [1. 1.]
'''

 

2、归一化

  归一化可以将稀疏的数据进行规范化,而且不会破坏其数据结构。归一化有两种,一种是归一化到[0,1]区间,另一种是归一化到[-1,1]区间内,这样是为了对付那些标准差相当小的特征并且保留下稀疏数据中的0值。

  在不涉及距离度量、协方差计算、数据不符合正太分布的时候,可以使用MinMaxScaler。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在[0 255]的范围。

 

[0,1]归一化:

对应的类:

  sklearn.preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True)

  • feature_range:要归一化的范围。
  • copy:是否拷贝数据。

 

类的方法:

  • fit_transform(self, X, y=None, **fit_params) 将数据传入并转化,一般传入特征数据X即可,目标数据Y不需要转化。
  • inverse_transform(self, X) 将数据的归一化去除,变回原来的数据。

 

计算公式:

  X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))

  X_scaled = X_std * (max - min) + min

  其中max、min为sklearn.preprocessing.MinMaxScaler中参数feature的参数范围,一般默认是0、1。X.min(axis=0)表示列最小值。

 

[-1,1]归一化 

对应的类:

  sklearn.preprocessing.MaxAbsScaler(copy=True)

 

类的方法:

  • fit_transform(self, X[, y])

 

代码示例:

import numpy as np
from sklearn.preprocessing import MinMaxScaler

x=np.arange(0,10).reshape(10,1)  #创建10*1数组
scale=MinMaxScaler()    #创建传化器
x_trans=scale.fit_transform(x)  #传入数据并转化
print(x_trans)

'''
结果为:
[[0.        ]
 [0.11111111]
 [0.22222222]
 [0.33333333]
 [0.44444444]
 [0.55555556]
 [0.66666667]
 [0.77777778]
 [0.88888889]
 [1.        ]]
'''

 

3、分位数标准化

  当含有较多的异常值的时候,普通的标准化不能很好的规范数据,所以要可以用分位数标准化,即用范围在第一分位数,第三分位数之间的数据的均值与方差来标准化数据,而不是所有的数据。

 

对应的类:

  sklearn.preprocessing.RobustScaler(with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)

  • with_centering:是否去中心化。
  • with_scaling:是否方差化。
  • quantile_range:分位数的范围,值为0-100之间。
  • copy:是否copy数据。

 

类的方法:

  • fit_transform(self, X[, y]) 传入数据并标准化。

 

代码示例:

import numpy as np
from sklearn.preprocessing import RobustScaler

x = np.random.normal(0, 1, [10, 1])  # 创建数据
x[0, 0] = 3  # 创建异常值
x_trans = RobustScaler().fit_transform(x)  # 标准化

print('x为:\n', x)
print('x_trans为:\n', x_trans)

'''
结果为:
x为:
 [[ 3.        ]
 [ 0.57042561]
 [ 1.15972829]
 [ 0.26299752]
 [-1.48938259]
 [-2.11549533]
 [ 0.43788961]
 [-1.87936541]
 [ 0.01614399]
 [ 0.44674289]]
x_trans为:
 [[ 1.60335674]
 [ 0.13312028]
 [ 0.48973183]
 [-0.05291724]
 [-1.11335529]
 [-1.49224213]
 [ 0.05291724]
 [-1.3493501 ]
 [-0.20229857]
 [ 0.05827473]]
'''

 

 

关于规范化的选择:

1、在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,StandardScaler表现更好。

2、在不涉及距离度量、协方差计算、数据不符合正太分布的时候,可以使用MinMaxScaler。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在[0 255]的范围。

 

二、连续特征二值化与离散特征编码(哑变量)

  对变量进行哑变量处理的原因是,有的模型不能够处理分类变量只能处理连续性变量,例如线性回归,所吧变量转化为用01编码的方式来表示有利于建模。

  one-hot用在GBDT、XGBoost这些模型里面都挺好的,但是用在逻辑回归里不行。因为逻辑回归要求变量间相互独立,如果你只有一个属性需要做one-hot编码还好,如果你有多个属性需要做one-ont编码,那么当某个样本的多个one-hot属性同时为1时,这两个属性就完全相关了,必然会导致singular error,也就是非奇异矩阵不能求解唯一解,得不出唯一的模型,但是你又不可能把同一个属性的某一个one-hot延伸变量删除。
  如果在逻辑回归中入模标称属性,可以直接替换成数值,然后做woe变换,用每个类别的woe值来代替原来的数值,这样既能够避免生成相关性强的变量,又能避开类别间大小无法比较的问题。

1、连续特征二值化

  将数据二值化,当数据小于等于某个值转化为0,大于某个值转化为1,可以将数据简化。

 

对应的类:

   sklearn.preprocessing.Binarizer(threshold=0.0, copy=True)

  • threshold:二值化阈值,<=threshold转化为0,>threshold转化为1
  • copy:是否拷贝数据。

 

类的方法:

  • fit_transform(self, X, y=None, **fit_params) 传入数据并二值化。

 

代码示例:

  

import numpy as np
from sklearn.preprocessing import Binarizer

x = np.random.normal(0,1,[5,1]) # 创建数据
x_trans = Binarizer().fit_transform(x)  # 二值化

print('x为:\n', x)
print('x_trans为:\n', x_trans)

'''
结果为:
x为:
 [[-1.61958613e+00]
 [-9.19743271e-04]
 [-1.08147857e+00]
 [-1.06551634e+00]
 [ 7.29322079e-01]]
x_trans为:
 [[0.]
 [0.]
 [0.]
 [0.]
 [1.]]
'''


2、离散特征二值化

  这个相当于哑变量编码。

 

对应的类:

   sklearn.preprocessing.LabelBinarizer(neg_label=0, pos_label=1, sparse_output=False)

  • neg_label:不属于该类的标签,默认为0。
  • pos_label:属于该类的标签,默认为1。
  • sparse_output:是否用稀疏矩阵格式输出,即索引加值的形式。

 

 

类的方法:

  • fit_transform(self, X, y=None, **fit_params) 传入数据并二值化。

 

的属性: 

  • LabelBinarizer().classes_ 用于查看二值化前离散特征原始值。

 

代码示例:

  

import numpy as np
from sklearn.preprocessing import Binarizer,LabelBinarizer

x = ['a','b','a','c'] # 创建数据
transor=LabelBinarizer()    #创建转化器具
x_trans = transor.fit_transform(x)  # 二值化

print('x为:\n', x)
print('转化的类别为:\n',transor.classes_)
print('x_trans为:\n', x_trans)

'''
结果为:
x为:
 ['a', 'b', 'a', 'c']
转化的类别为:
 ['a' 'b' 'c']
x_trans为:
 [[1 0 0]
 [0 1 0]
 [1 0 0]
 [0 0 1]]
'''

 

3、哑变量on-hot编码

  将离散型数据转化为哑变量。

 

对应的类:

   sklearn.preprocessing.OneHotEncoder(n_values=None, categorical_features=None, categories=None, drop=None, sparse=True, dtype=<class ‘numpy.float64’>, handle_unknown=’error’)

  • **n_values:可选值[None,'auto',int],用几个值(即几列0、1编码)来表示特征的离散值,默认是对单个特征,有几个离散值就有几个值对应。自己指定,如果学历分为[高,中,低],但是样本只有[高,低],为了把学历中也表示出来,就需要传入3。
  • **categorical_features:指定了对哪些训练特征(即那些列)进行编码,默认对所有训练特征都进行编码。也可以自己指定选择哪些特征,通过索引或者 bool 值来指定,例如对列[a,b,c]中的列[a,b]编码,则传入[a,b]。
  • categories:可选值['auto',list]。'auto'默认将特征的所有离散值转化。如果是list,则将保留categories[list]对应的离散值。一般默认就好。
  • drop:可选值[None,'first',list]。默认None表示将所有的离散值转化;'first',去掉第一个特征再将离散值转化,编码后全为0的表示第一个离散值;list:指定去除的离散值。建议默认就好。
  • **sparse:True返回稀疏矩阵,索引加值的矩阵。
  • dtype:数据类型。
  • handle_unknown:对空值怎么处理,‘error’ 表示报错,‘ignore’表示忽略。

 

类的方法:

  • fit_transform(self, X, y=None, **fit_params) 传入数据并二值化。
  • get_feature_names() 返回编码后的列的名字,形式为:特证名_离散值。

 

代码示例:

 

import numpy as np
from sklearn.preprocessing import OneHotEncoder

x = np.array([['a'],['b'],['a'],['c']]) # 创建数据
transor=OneHotEncoder(sparse=False)    #创建转化器具
x_trans = transor.fit_transform(x) # 二值化


print('x为:\n', x)
print('编码的后的列为:\n',transor.get_feature_names())
print('x_trans为:\n', x_trans)

'''
结果为:
x为:
 [['a']
 ['b']
 ['a']
 ['c']]
 编码的后的列为:
 ['x0_a' 'x0_b' 'x0_c']
x_trans为:
 [[1. 0. 0.]
 [0. 1. 0.]
 [1. 0. 0.]
 [0. 0. 1.]]
'''

 

4、pandas中的哑变量编码

对应函数:

  pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)

  •  data:传入的数据,数组、Series类或者dataframe类。
  • prefix:编码后列名的前缀,默认用特征名做为前缀,例如性别特征,编码后的列为[性别_男,性别_女]。如果要传入,长度要和特征数相同。
  • prefix_sep:编码后列名的间隔符,默认就好。
  • dummy_na:是否对NaNs类的数据进行单独的编码,否的话忽略NaNs数据。
  • sparse:是否输出稀疏矩阵,即index+值。
  • drop_first:是否去除第一个离散值再编码。
  • dtype:数据类型。

 

代码示例:

import pandas as pd

df=pd.DataFrame(data=[['a'],['b'],['c'],['a']],columns=['grade'])

df_dum=pd.get_dummies(df)
print(df_dum)


'''
结果为:
      grade_a  grade_b  grade_c
0        1        0        0
1        0        1        0
2        0        0        1
3        1        0        0
'''

 

 

三、缺失值插补

1、单变量插补

  即只根据特征自身来进行缺失值的补充。

 

对应的类:

  sklearn.impute.SimpleImputer(missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True, add_indicator=False)

  • missing_values:缺失值,用什么表示缺失值。默认是np.nan
  • 'strategy:插补缺失值的方法,'mean':均值;'median':中位数;'most_frequent':频数最高的数;'constant':用蚕食fill_value的值代替。
  •  fill_value:参数strategy='constant'时用来替换缺失值的值。
  • add_indicator:若为True则替换后对数据添加是否插补缺失值的标签。

 

类的方法:

  • fit_transform(self, X, y=None, **fit_params) 传入数据补充缺失值。

 

代码示例:

from sklearn.impute import SimpleImputer
import numpy as np

x=np.array([1,2,3,4,5,6,7,8,np.nan,10]).reshape(10,1)
imp=SimpleImputer(np.nan)
x_imp=imp.fit_transform(x)

print(x_imp)


'''
结果为:
[[ 1.        ]
 [ 2.        ]
 [ 3.        ]
 [ 4.        ]
 [ 5.        ]
 [ 6.        ]
 [ 7.        ]
 [ 8.        ]
 [ 5.11111111]
 [10.        ]]
'''

 

2、多变量插补法

  缺失值的插补也可以通过利用多变量建模的方式来插补,例如用knn、随机森林、贝叶斯估计等,可以用不同的插补法,在建模后通过不通的模型效果来选择最合适的。

  sklearn这里允许我们自己选择建模的方式,使用迭代器  IterativeImputer 类(这个类还在试验阶段),该类将每个 missing value 的特征建模为其他特征的函数,并使用该估计进行插补。它是以循环的方式实现的:在每个步骤中,一个特征列被指定为输出 y,而其他特征列被视为输入 X 。对于已知 y,回归量适合(X,y)。然后,回归量用于预测 y 的缺失值。对于 n 迭代方式,然后对 max-iter 插补轮进行重复。最后一轮插补的结果被返回。

 

对应的类:

  sklearn.impute.IterativeImputer(estimator=None, missing_values=nan, sample_posterior=False, max_iter=10, tol=0.001, n_nearest_features=None, initial_strategy=’mean’, imputation_order=’ascending’, min_value=None, max_value=None, verbose=0, random_state=None, add_indicator=False)

  • estimator :estimator对象,默认= BayesianRidge()。循环法插补的每一步使用的估算器。如果sample_posterior为True,则估算器必须支持 return_std其predict方法。
  • missing_values :指定何种占位符表示缺失值,可选 number ,string ,np.nan(default) ,None
  • sample_posterior :布尔值,默认为False,是否从每个插补的拟合估计的(高斯)预测后验进行采样。如果设置为True,Estimator 必须支持return_std 其predict 方法。True如果IterativeImputer用于多个插补,则设置为 。
  • max_iter :输入为int型数据,默认值是10。在返回最后一轮计算的估算值之前要执行的最大插补轮次数。
  • tol :容忍停止条件
  • n_nearest_features :用于估计每个要素列的缺失值的其他要素数。使用每个特征对之间的绝对相关系数(在初始插补之后)测量特征之间的接近度。为了确保在整个插补过程中覆盖特征,邻居特征不一定是最接近的,而是以与每个插补目标特征的相关性成比例的概率绘制。当功能数量巨大时,可以提供显着的加速。如果None,将使用所有功能。
  • initial_strategy :使用哪种策略初始化缺失值。与 SimpleImputer 中的strategy参数相同
  • imputation_order :排序规则
    • ascending :从缺失值最少的功能到最多
    • descending :从具有最多缺失值的功能到最少
    • roman :左到右
    • arabic :右到左
    • random :随机顺序
  • min_value :最小可能的估算值。默认值None将最小值设置为负无穷大。
  • max_value :最大可能的估算值。默认值None将最大值设置为正无穷大。
  • verbose :详细程度标志控制在评估函数时发出的调试消息。越高越详细。可以是0,1或2。
  • random_state :伪随机数生成器的种子使用。如果 n_nearest_features不是None,imputation_order则随机选择估计器特征, if random和后验if的采样sample_posterior为True。
  • add_indicator :如果为True,则MissingIndicator变换将堆叠到imputer的变换的输出上。这允许预测估计器尽管插补而解释缺失。如果某个要素在拟合/训练时没有缺失值,即使在变换/测试时缺少值,该要素也不会出现在缺失的指示符上。

 

类的方法:

  • fit_transform(self, X, y=None) 用来插补缺失值

 

代码示例:

from sklearn.experimental import enable_iterative_imputer   #要先导入这个才能正常使用
from sklearn.impute import IterativeImputer
import numpy as np

imp = IterativeImputer(max_iter=10, random_state=0)
imp.fit([[1, 2], [3, 6], [4, 8], [np.nan, 3], [7, np.nan]])
X_test = [[np.nan, 2], [6, np.nan], [np.nan, 6]]
print(np.round(imp.transform(X_test)))


'''
结果为:
[[ 1.  2.]
 [ 6. 12.]
 [ 3.  6.]]
'''

 

3、impyute一个多变量缺失值插补包

  除了sklearn之外,还有两个常用的缺失值插补的包impytue和fancyimpute,除了简单的单变量之外,还支持多变量插补。由于 fancyimpute由于包安装不成功,所以这里不做介绍,impyute包,这里只列出相关的缺失值插补方法与一个简单示例。

fast_knn 快速knn算法
mice mice算法
mean 均值填充

 

代码示例:

  这里有三种方法的实现,分别用三个函数:fast_knn, mice, mean,然后计算拟合缺失值的误差,然后计算出那个算法的误差最大,循环100次,最后输出各个算法误差最大的次数。

  这里每次结果都不一样,但是knn和mice的算法的误差比mean的误差大的次数要少,所以一般建议可以使用knn或者mice算法。

from impyute.imputation.cs import fast_knn, mice, mean
from sklearn.datasets import load_iris
import numpy as np

iris = load_iris()
x = iris.data

#记录三种方法误差最大的次数,初始为0
knn_cnt = 0
mice_cnt = 0
mean_cnt = 0

for i in range(99):
    #第2列的数据随机添加缺失值
    rand_x = np.random.randint(0, 150, 10)
    x_copy = np.copy(x)
    x_copy[rand_x, 1] = np.nan

    #用三种方法插补缺失值
    x1 = fast_knn(x_copy, 4)
    x2 = mice(x_copy)
    x3 = mean(x_copy)

    knn_error = np.abs(np.sum(x1[rand_x, 1] - x[rand_x, 1]))  # knn误差
    mice_error = np.abs(np.sum(x2[rand_x, 1] - x[rand_x, 1]))  # mice误差
    mean_error = np.abs(np.sum(x3[rand_x, 1] - x[rand_x, 1]))  # mean误差

    #如果误差最大,则算法次数加1
    if knn_error == max(knn_error, mice_error, mean_error):
        knn_cnt += 1
    elif mice_error == max(knn_error, mice_error, mean_error):
        mice_cnt += 1
    else:
        mean_cnt += 1

#输出误差最大的次数
print(knn_cnt, mice_cnt, mean_cnt)

 

 

4、github上基于sklearn的一个多变量缺失值插补包  

  这个包在github上可以找到,叫MissingImputer,这个包可以通过利用knn, randomforest, xgboost, lightgbm的方法来填补缺失值,数据的训练和拟合方法和sklearn一样,所以很推荐使用,需要注意的时它需要额外的包xgboost和lightgbm,可以通过pip进行安装即可。

 

对应的类:

  MissingImputer(max_iter=10, ini_fill = True, ini_strategy_reg = 'mean', ini_strategy_clf = 'most_frequent', with_cat = False, cat_index = None, tol = 1e-3, model_reg = "knn", model_clf = "knn")

  • max_iter:迭代次数,模型一开始用简单数据填充缺失,然后训练模型并拟合缺失,然后用拟合了缺失的数据继续训练拟合,重复直到迭代结束。
  • ini_fill:是否要进行简单填补(False仅对xgb和lgb有效)。
  • ini_strategy_reg:连续变量简单填补规则, mean or median。
  • ini_strategy_clf:离散变量简单填补规则, only most_frequent。
  • cat_index:离散变量索引(int)。
  • tol:阈值。
  • model_reg:连续变量采用的预测缺失值模型, be xgboost,lightgbm, randomforest, knn。
  • model_clf:离散变量采用的预测缺失值模型

 

类的方法:

  MissingImputer.fit()训练,MissingImputer. transform()拟合缺失值。

 

示例代码:

from MissingImputer.ModelBasedImputer.MissingImputer import MissingImputer
from sklearn.datasets import load_iris
import numpy as np

iris = load_iris()
x = iris.data


rand_x = np.random.randint(0, 150, 10)  # 0-150取10个随机数作为随机航
x_copy = np.copy(x)
x_copy[rand_x, 1] = np.nan  # 这10个随机行添加缺失值

model=MissingImputer()
model.fit(x)    # 训练
x=model.transform(x)    # 拟合

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!