文章目录
1.缺失值处理
这里使用sklearn.impute库中的SimpleImputer模块进行缺失值的处理
import numpy as np
from sklearn.impute import SimpleImputer
'''
参数:
missing_values: number, string, np.nan (default) or None
指定缺失值参数,默认为np.nan
strategy: string, default=’mean’
缺失值补全策略参数,默认为均值补全
还可以是:
中位数(median)
常数(constant)
最高频数(most_frequent)
'''
imp_mean = SimpleImputer(missing_values = np.nan, strategy = 'mean')
imp_median = SimpleImputer(missing_values = np.nan, strategy = 'median')
imp_constant = SimpleImputer(missing_values = np.nan, strategy = 'constant')
imp_most_frequent = SimpleImputer(missing_values = np.nan, strategy = 'most_frequent')
X = [[13, 22], [5, 3], [7, np.nan], [np.nan, 5], [3, 7]]
imp_mean.fit(X)
imp_median.fit(X)
imp_constant.fit(X)
imp_most_frequent.fit(X)
print("均值处理结果如下:")
print(imp_mean.transform(X))
print("中位数处理结果如下:")
print(imp_median.transform(X))
print("常数处理结果如下:")
print(imp_constant.transform(X))
print("最高频数处理结果如下:")
print(imp_most_frequent.transform(X))
输出
均值处理结果如下:
[[13. 22. ]
[ 5. 3. ]
[ 7. 9.25]
[ 7. 5. ]
[ 3. 7. ]]
中位数处理结果如下:
[[13. 22.]
[ 5. 3.]
[ 7. 6.]
[ 6. 5.]
[ 3. 7.]]
常数处理结果如下:
[[13. 22.]
[ 5. 3.]
[ 7. 0.]
[ 0. 5.]
[ 3. 7.]]
最高频数处理结果如下:
[[13. 22.]
[ 5. 3.]
[ 7. 3.]
[ 3. 5.]
[ 3. 7.]]
2. 数据的规范化
2.1 缩放规范化
2.1.1 最大值-最小值缩放
将数据按照比例缩放,使之落入一个较小的特定区间,如[0, 1]。
计算公式如下:xi - 最小值 / (最大值 - 最小值)
# 使用numpy库生成缺失值
# 引用sklearn.processing库,其中包含绝大部分额的数据预处理方法
import numpy as np
from sklearn import preprocessing
# 原始数据X
X = np.array([[3, -2, 2], [2, 0, 0], [-1, 1, 3]])
# 初始化数据预处理器
min_max_scaler = preprocessing.MinMaxScaler()
#数据转换并打印
X_minmax = min_max_scaler.fit_transform(X)
print("缩放结果如下:")
print(X_minmax)
print("输出其缩放倍数:") # 这里max、min 为区间的边界,默认1,0
print(min_max_scaler.scale_) # (max - min) / (X.max(axis=0) - X.min(axis=0))
print("输出每一列的最小调整:")
print(min_max_scaler.min_) # min - X.min(axis=0) * self.scale_
print("输出每一列的最小值:")
print(min_max_scaler.data_min_)
输出
缩放结果如下:
[[1. 0. 0.66666667]
[0.75 0.66666667 0. ]
[0. 1. 1. ]]
输出其缩放倍数:
[0.25 0.33333333 0.33333333]
输出每一列的最小调整:
[0.25 0.66666667 0. ]
输出每一列的最小值:
[-1. -2. 0.]
2.1.2 最大绝对值缩放
公式如下:x / X.max
取值范围为[-1, 1]
from sklearn import preprocessing
import numpy as np
# 初始数据X
X = np.array([[3, -2, 2], [2, 0, 0], [-1, 1, 3]])
#初始化数据预处理器
max_abs_scaler = preprocessing.MaxAbsScaler()
X_maxabs = max_abs_scaler.fit_transform(X)
print("最大值缩放结果如下:")
print(X_maxabs)
2.1.3 自定义缩放区间
最小值-最大值缩放可以预先设置特定的范围,数据转换公式如下:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min
X_scaled表示设定最大值、最小值之后的缩放变换输出,max、min分别表示设定的最大值和最小值
X = np.array([[3, -2, 2], [2, 0, 0], [-1, 1, 3]])
#feature_range(min, max)参数, 设置min和max的值
min_max_scaler = preprocessing.MinMaxScaler(feature_range = (-2, 6))
X_minmax = min_max_scaler.fit_transform(X)
print("自定义最大值和最小值的缩放结果:")
print(X_minmax)
输出
自定义最大值和最小值的缩放结果:
[[ 6. -2. 3.33333333]
[ 4. 3.33333333 -2. ]
[-2. 6. 6. ]]
当新加入样本时,如果样本中的某个特征值的数值超出了原先最大值或最小的范围,则会引起最大值或者最小值的更新,即最大值和最小值存在不稳定的情况,下面我们来看一个例子
X = np.array([[3, -2, 2], [2, 0, 0], [-1, 1, 3]])
#feature_range(min, max)参数, 设置min和max的值
min_max_scaler = preprocessing.MinMaxScaler()
X_minmax = min_max_scaler.fit_transform(X)
#引入新数据
X_new = np.array([[-3, -1, 4]])
X_new_minmax = min_max_scaler.transform(X_new)
print("缩放结果如下:")
print(X_new_minmax)
缩放结果如下:
[[-0.5 0.33333333 1.33333333]]
2.2 标椎化
使数据满足正态分布——均值为0、标准差为1,公式如下:z =(x-u)/ s
from sklearn import preprocessing
import numpy as np
X = np.array([[3, -2, 2], [2, 0, 0], [1, 2, 3]])
standard_scaler = preprocessing.StandardScaler()
X_stand_scaler = standard_scaler.fit_transform(X)
print("标椎化变换结果如下:")
print(X_stand_scaler)
print("输出标准化之后的均值:")
print(X_stand_scaler.mean(axis = 0))
print("输出标准化之后的方差")
print(X_stand_scaler.std(axis = 0))
标椎化变换结果如下:
[[ 1.22474487 -1.22474487 0.26726124]
[ 0. 0. -1.33630621]
[-1.22474487 1.22474487 1.06904497]]
输出标准化之后的均值:
[ 0.00000000e+00 0.00000000e+00 -7.40148683e-17]
输出标准化之后的方差
[1. 1. 1.]
之前调用的是类接口,函数调用的代码实现如下:
X_standard = preprocessing.scale(X)
print(X_standard)
输出
[[ 1.22474487 -1.22474487 0.26726124]
[ 0. 0. -1.33630621]
[-1.22474487 1.22474487 1.06904497]]
2.3 范数规范化
范数公式如下: ||x|| = sum(xip)(1/p)
当p = 1时,称为L1范式,求的是曼哈顿距离
当p = 2是,称为L2范式,求的是欧式距离
当p = 无穷时,其结果为|x|max
范数正则化即:向量中每个元素除以向量的范数。设范数函数为norm(x),则如公式下:
xi(k) = xi(k) / norm(x)
函数实现
# 这里使用normalize函数来实现,通过设置norm来指定范数,还可以是l1和max等
X_norm = preprocessing.normalize(X, norm = 'l2')
print("范数L2规范化变换之后的输出:")
print(X_norm)
范数L2规范化变换之后的输出:
[[ 0.72760688 -0.48507125 0.48507125]
[ 1. 0. 0. ]
[ 0.26726124 0.53452248 0.80178373]]
类实现
normalizer = preprocessing.Normalizer(norm = 'l1').fit(X)
print("范数L1规范化变换之后的输出:")
print(normalizer.transform(X))
输出
范数L1规范化变换之后的输出:
[[ 0.42857143 -0.28571429 0.28571429]
[ 1. 0. 0. ]
[ 0.16666667 0.33333333 0.5 ]]
3. 非线性变换
3.1 二分类变换
设定一个阙值a,待转换的数值 > a, 输出1,否则输出0
from sklearn import preprocessing
import numpy as np
X = np.array([[3, -2, 2], [2, 0, 0], [1, 2, 3]])
binarizer = preprocessing.Binarizer(threshold=-1) # 设置阙值为1
X_binarizer = binarizer.fit_transform(X)
print(X_binarizer)
输出:
[[1 0 1]
[1 1 1]
[1 1 1]]
3.2 分位数变换
通过设置分割点将是数据切分为概率相等的几个不同的区间。统计学中常以四分位数为例
我们利用sklearn自带的数据集包sklearn.datasets加载鸢尾花数据集进行分位数的代码实现
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
import numpy as np
iris = load_iris()
# 得到数据的特征和标签
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 0)
# 初始化分位数转化器
quantile_transform = preprocessing.QuantileTransformer(random_state = 0)
X_train_trans = quantile_transform.fit_transform(X_train)
X_test_trans = quantile_transform.fit_transform(X_test)
print("被转化训练集的五分位数")
print(np.percentile(X_train[:,0], [0, 25, 50, 75, 100]))
print("被转化训练集的五分位数")
print(max(X_train[:,0]))
print("被转化训练集五分位数中的第三位")
print(np.median(X_train[:,0]))
print("被转化训练集五分位数中的第一位")
print(min(X_train[:,0]))
输出:
被转化训练集的五分位数
[4.3 5.1 5.8 6.5 7.9]
被转化训练集的五分位数
7.9
被转化训练集五分位数中的第三位
5.8
被转化训练集五分位数中的第一位
4.3
下面我们从直观上感受分位数变换对不同的转化情况
import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import QuantileTransformer
from sklearn.model_selection import train_test_split
# 设置参数
N_SAMPLES = 1000
size = (N_SAMPLES)
#初始化随机数发生器
rng = np.random.RandomState(304)
#生成lognormal分布
X_lognormal = rng.lognormal(size = size)
#生成高斯分布
loc = 100
X_gaussian = rng.normal(loc = loc, size = size)
#生成均匀分布
X_uniform = rng.uniform(low = 0, high = 1, size = size)
# 将要展示的分布数据
distributions = [
('Lognormal', X_lognormal),
('Gaussian', X_gaussian),
('Uniform', X_uniform),
('Lognormal after uniform', []),
('Gaussian after uniform', []),
('Uniform after uniform', []),
('Lognormal after normal', []),
('Gaussian after normal', []),
('Uniform after normal', []),
]
# 图表初始化
f, ax = plt.subplots(ncols = 3, nrows = 3, figsize = (12, 8))
for i,d in enumerate(distributions):
# 配置位置坐标信息
a = int(np.floor(i / 3))
b = np.mod(i, 3)
title,data = d
if data != []:
sns.distplot(data, kde = False, rug = True, ax = ax[a, b], color = 'r').set_title(title)
else:
_,data = distributions[b]
X_train, X_test = train_test_split(data, test_size = 0.5)
X_train = X_train.reshape(-1, 1)
X_test = X_test.reshape(-1, 1)
#在分位数分布中,可以采用俩种分布策略,即均匀分布(uniform)和正态分布(normal)
strategy = title.split()[2]
show_data = QuantileTransformer(output_distribution=strategy,
random_state = rng).fit(X_train).transform(X_test)
sns.distplot(show_data, kde = False, rug = True, ax = ax[a, b])
ax[a, b].set_title(title)
plt.show()