Python sklearn学习之数据预处理——非线性转换

Python sklearn学习之数据预处理——非线性转换

1. 两种常见的非线性转换

1.1 分位数转换

  • 基本公式

y=G1(F(x)) y = G^{-1}(F(x))

  • 公式说明
    • x:特征
    • F:特征的累积分布函数
    • G^(-1):期望输出值分布G的分位数函数
  • 目的:将所有特征置于相同的期望分布中
  • 公式成立的事实说明
    • 如果X是具有连续累积分布函数F的随机变量,那么F(X)均匀分布在[0,1]
    • 如果U是在[0,1]上的随机分布,那么G^(-1)(U)有分布G.

累积分布函数:是概率密度函数的积分

概率密度函数:表示瞬时幅值落在某指定范围内的概率

设累积分布函数为F,概率密度函数为f,则可表示如下:
Fx(x)=xfx(t)dt F_x(x) = \displaystyle \int^{x}_{-\infty}f_{x}(t)dt

  • 分位数转换优势:平滑了异常分布,并且比缩放方法受异常值的影响更小
  • 分位数转换缺点:使特征间及特征内的关联和距离失真了

1.2 幂变换

本质是一组参数变换,其目的是将数据从任意分布映射到接近高斯分布的位置

2. sklearn中非线性变换的实现

2.1 映射到均匀分布

sklearn 将数据集映射到均匀分布的方式主要是通过分位数转换的方式实现,通过类QuantileTransformer 类以及quantile_transform 函数实现。

2.1.1QuantileTransformer类
  • 类定义
def __init__(self, n_quantiles=1000, output_distribution='uniform',
                 ignore_implicit_zeros=False, subsample=int(1e5),
                 random_state=None, copy=True):
  • 参数说明

    • n_quantilesint,optional(默认值= 1000或n_samples)
      • 要计算的分位数。它对应于用于离散累积分布函数的标记的数量。如果n_quantiles大于样本数,则n_quantiles被设置为样本数,因为较大数量的分位数不能给出累积分布函数估计器的更好近似。
    • output_distributionstr,optional(default =‘uniform’)
      • 转换数据的边际分布。选择是“uniform”(默认)或“normal”
    • ignore_implicit_zerosboolean,optional(默认值= False)
      • 仅适用于稀疏矩阵。如果为True,则丢弃矩阵的稀疏条目以计算分位数统计。如果为False,则将这些条目视为零
    • subsampleint,optional(default = 1e5)
      • 用于估计计算效率的分位数的最大样本数。注意,对于值相同的稀疏矩阵和密集矩阵,子采样过程可能不同
    • random_state : int,RandomState实例或None,可选(默认=None)
      • 如果是int,则random_state是随机数生成器使用的种子; 如果是RandomState实例,则random_state是随机数生成器; 如果为None,则随机数生成器是np.random使用的RandomState实例。请注意,这通过二次采样和平滑噪声来使用。
    • copy :略
  • 对象属性

    • n_quantiles_ 用于离散累积分布函数的实际分位数

    • quantiles_: 值与参考对应之间的分位数矩阵

    • references_:

      n_samples = X.shape[0] # 数组维度元组,或者说是样本数
      self.n_quantiles_ = max(1, min(self.n_quantiles, n_samples)) # 得到样本数与分数数较小的值,为了防止传入空数组,所以需保证大于1
      self.references_ = np.linspace(0, 1, self.n_quantiles_,endpoint=True)
      
  • 例子

X_train_trans = preprocessing.QuantileTransformer(random_state=0).fit_transform(X_train)
  • quantile_transform 函数

一如既往,quantile_transform 函数只是本质上也是创建QuantileTransformer 转换器

n = QuantileTransformer(n_quantiles=n_quantiles,
                            output_distribution=output_distribution,
                            subsample=subsample,
                            ignore_implicit_zeros=ignore_implicit_zeros,
                            random_state=random_state,
                            copy=copy)
if axis == 0:
	return n.fit_transform(X)
elif axis == 1:
	return n.fit_transform(X.T).T
else:
	raise ValueError("axis should be either equal to 0 or 1. Got"
	" axis={}".format(axis))

2.2 映射到高斯分布

幂变换是一类参数化的单调变换, 其目的是将数据从任何分布映射到尽可能接近高斯分布,以便稳定方差和最小化偏斜。

PowerTransformer 类提供了两种幂变换,Yeo-Johnson transformthe Box-Cox transform

2.2.1 Yeo-Johnson transform变换

在这里插入图片描述

2.2.2 the Box-Cox transform变换

在这里插入图片描述

2.2.3 类说明
def __init__(self, method='yeo-johnson', standardize=True, copy=True):
  • 参数说明

    • method :可选,接受一个字符串值,默认是 ‘yeo-johnson’
      • ’yeo-johnson’ :指明幂变换方式以 Yeo-Johnson transform 方式实现,此种方式下数据集可以含有正负值
      • the Box-Cox transform :指明幂变换方式以the Box-Cox transform 方式实现,此种方式下数据集只能是正值,不允许有负值
    • standardize :可选,接受一个boolean值,默认是 ‘True’ ,设置为True可将零均值单位方差归一化应用于变换后的输出
    • copy :略
  • 属性

    • lambdas_ : 得到一个浮点数组,转换过程中所选择的参数
    self.lambdas_ = np.array([optim_function(col) for col in X.T])
    
  • 例子

power = preprocessing.PowerTransformer(method='box-cox', standardize=False, copy=True)
X_lognormal = np.random.RandomState(616).lognormal(size=(3, 3))
power.fit_transform(X_lognormal)
# 注意没有下面这种使用方式
# power.fit(X_lognormal).transform(X_lognormal)
  • power_transform 函数

本质上是构造 PowerTransformer 对象并调用 fit_transform 实现

pt = PowerTransformer(method=method, standardize=standardize, copy=copy)
return pt.fit_transform(X)
2.2.4 拓展

实际上,利用2.1.1中的 QuantileTransformer 类也可以讲数据集转换为正态分布(通过设置 output_distribution=‘normal’)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章