上一章我们介绍了如何进行基本的数据清洗工作。加下来我们来看看如何进行特征转换,学统计学的小伙伴一定知道什么是标准化,这其实就是一种特征转换,在一些模型中,特征转换是有必要的。(例如某些神经网络问题,使用特征转换可以收敛更快)
min-max缩放的基本思想是将所有的数据都转换到了某一固定区间,默认的是转换到0-1,其中最小的数据为0,最大的数据为1,变换公式如下:

下面来看看如何使用代码实现:
首先导入相关库
import numpy as np
from sklearn import preprocessing #处理数据预处理包# 首先我们建立一个特征
feature = np.array([[-500.5],
[-100.1],
[0],
[100.1],
[900.9]])
featurearray([[-500.5],
[-100.1],
[ 0. ],
[ 100.1],
[ 900.9]])下面我们使用MinMaxScaler()进行特征缩放,具体代码和结果如下
# 1.创建min_max缩放器
minmax_feature = preprocessing.MinMaxScaler()
# 2.对我们要装换的数据进行缩放
scaled_feature = minmax_feature.fit_transform(feature)
scaled_featurearray([[0. ],
[0.28571429],
[0.35714286],
[0.42857143],
[1. ]])
拓展:MinMaxScaler()默认会返回到==0-1==之间,但是有的时候我们希望转换到-1到1之间,或者==0-2==之间,我们可以进行相关定义,具体代码如下:
minmat_0_2 = preprocessing.MinMaxScaler((0,2))
scaled_feature = minmat_0_2.fit_transform(feature)
scaled_featurearray([[0. ],
[0.57142857],
[0.71428571],
[0.85714286],
[2. ]])
标准化缩放是我们应用最广泛的方法之一,尤其在统计学当中,我们在建立一些统计模型时,往往先把数据标准化处理。尤其在统计推断中,根据中心极限定理,当数据足够多,我们往往对数据进行标准化之后认为其满足标准正态分布或近似满足标准正态分布,具体公式如下:

scikit-learn的StandardScaler# 创建特征
feature = np.array([[-1000.1],
[-200.2],
[500.5],
[600.6],
[9000.9]])# 创建缩放器
scaler = preprocessing.StandardScaler()# 标准化
standard = scaler.fit_transform(feature)standardarray([[-0.76058269],
[-0.54177196],
[-0.35009716],
[-0.32271504],
[ 1.97516685]])标准化使用的比minmax更为常见,转换后认为其服从标准正态分布,下面我们来看一下标准化后数据的均值和标准差
print('mean:', round(standard.mean()))
print('std:', standard.std())mean: 0
std: 1.0==拓展==:如果数据存在很严重的异常值,可能会影响特征的平均值和方差,也会对标准化早造成不好的影响,我们一般使用中位数和四分位数间距来进行缩放,默认转换规则如下:

具体代码和结果如下
# 创建缩放器,默认是以中位数进行缩放
robust_scaler = preprocessing.RobustScaler()robust_scaler.fit_transform(feature)array([[-1.87387612],
[-0.875 ],
[ 0. ],
[ 0.125 ],
[10.61488511]])
归一化处理是一种去量纲比较常用的方法,例如在层次分析法中,我们会使用归一化处理 主要分为L1和L2归一化,在Normalizer()中,默认是L2归一化,假设有一个m×n的矩阵,两种方法的公式如下:

L1归一化基本思想是使得每一行相加等于1

L2归一化基本思想是使得每一行平方相加等于1
具体代码实现如下
Normalizer()默认是==L2==归一化
feature = np.array([[0.5, 0.5],
[1.1, 3.4],
[1.5, 20.2],
[1.63, 34.4],
[10.9, 3.3]])normalizer = preprocessing.Normalizer()normalized = normalizer.fit_transform(feature)normalizedarray([[0.70710678, 0.70710678],
[0.30782029, 0.95144452],
[0.07405353, 0.99725427],
[0.04733062, 0.99887928],
[0.95709822, 0.28976368]])# 如果以l1范数来归一化,则如下代码,他使每一行的和相加为1
normalized2 = preprocessing.Normalizer(norm='l1').transform(feature)normalized2array([[0.5 , 0.5 ],
[0.24444444, 0.75555556],
[0.06912442, 0.93087558],
[0.04524008, 0.95475992],
[0.76760563, 0.23239437]])degree参数选择多项式的最高阶数interaction_only可以选择只有交互项features = np.array([[2,3]])polynomial = preprocessing.PolynomialFeatures(degree=2)polynomial.fit_transform(features)array([[1., 2., 3., 4., 6., 9.]])# 此时把0次向也放在里面
polynomial = preprocessing.PolynomialFeatures(degree=2, include_bias=False)#此时不包括0此项
polynomial.fit_transform(features)array([[2., 3., 4., 6., 9.]])# 设置只包含交互项
interaction = preprocessing.PolynomialFeatures(degree=2,
interaction_only=True, include_bias=False)interaction.fit_transform(features)array([[2., 3., 6.]])# 使用FunctionTransform 对一组特征应用一个函数
def add_ten(x):
return x+10
ten_transformer = preprocessing.FunctionTransformer(add_ten,validate=False)ten_transformer.transform(features)array([[12, 13]])上述和pandas使用apply函数是一样的效果
import pandas as pd
houses = pd.DataFrame()houses['Price'] = [534433, 392333, 293222, 4322032]
houses['Bathrooms'] = [2, 3.5, 2, 116]
houses['Squre_Feet'] = [1500, 2500, 1500, 48000]# 1.删选观察值
houses[houses['Bathrooms']<20].dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
| Price | Bathrooms | Squre_Feet | |
|---|---|---|---|
| 0 | 534433 | 2.0 | 1500 |
| 1 | 392333 | 3.5 | 2500 |
| 2 | 293222 | 2.0 | 1500 |
# 第二种思路,将异常值标记,并作为数据的一个特征
houses['Outlier'] = np.where(houses['Bathrooms']<20, 0, 1)#小于20的即为1houses.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
| Price | Bathrooms | Squre_Feet | Outlier | |
|---|---|---|---|---|
| 0 | 534433 | 2.0 | 1500 | 0 |
| 1 | 392333 | 3.5 | 2500 | 0 |
| 2 | 293222 | 2.0 | 1500 | 0 |
| 3 | 4322032 | 116.0 | 48000 | 1 |
# 第三种思路
houses['Log_of_Squre_Feet'] = [np.log(x) for x in houses['Squre_Feet']]houses.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
| Price | Bathrooms | Squre_Feet | Outlier | Log_of_Squre_Feet | |
|---|---|---|---|---|---|
| 0 | 534433 | 2.0 | 1500 | 0 | 7.313220 |
| 1 | 392333 | 3.5 | 2500 | 0 | 7.824046 |
| 2 | 293222 | 2.0 | 1500 | 0 | 7.313220 |
| 3 | 4322032 | 116.0 | 48000 | 1 | 10.778956 |
因为异常值会对均值和标准差都造成较大的影响,所以一般使用对异常值鲁棒性更高的放缩方法,例如之前介绍的RobustScaler
基本思路是根据给一个阈值将特征离散化。
Binarizerfrom sklearn.preprocessing import Binarizerage = np.array([[6],[12],[20],[36],[65]])binary = Binarizer(18)binary.fit_transform(age)array([[0],
[0],
[1],
[1],
[1]])numpy 将设定多个阈值来使特征离散化np.digitize(age, bins=[20, 30, 64])array([[0],
[0],
[1],
[2],
[3]], dtype=int64)阈值的设定是左闭右开 所以第一个区间不包括20。
阅读量:1602
点赞量:0
收藏量:0