sklearn学习笔记(一):数据预处理

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()

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43328040/article/details/107454219