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

article/2025/8/8 10:00:05

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

文章目录

    • Python sklearn学习之数据预处理——非线性转换
      • 1. 两种常见的非线性转换
        • 1.1 分位数转换
        • 1.2 幂变换
      • 2. sklearn中非线性变换的实现
        • 2.1 映射到均匀分布
          • 2.1.1QuantileTransformer类
        • 2.2 映射到高斯分布
          • 2.2.1 Yeo-Johnson transform变换
          • 2.2.2 the Box-Cox transform变换
          • 2.2.3 类说明
          • 2.2.4 拓展
      • 3. 其他数据预处理
        • 3.1 归一化
          • 3.1.1 normalize函数
          • 3.1.2 Normalizer 工具类
      • 4. 类别特征编码
        • 4.1 OrdinalEncoder类
        • 4.2 OneHotEncoder类
      • 5 离散化
        • 5.1 KBinsDiscretizer
        • 5.2 特征二值化
      • 6. 生产多项式特征
      • 7. 自定义转换器

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

1.1 分位数转换

  • 基本公式

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

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

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

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

设累积分布函数为F,概率密度函数为f,则可表示如下:
F x ( x ) = ∫ − ∞ x f x ( t ) d t F_x(x) = \displaystyle \int^{x}_{-\infty}f_{x}(t)dt Fx(x)=xfx(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’)。

3. 其他数据预处理

3.1 归一化

归一化缩放单个样本以具有单位范数 的过程。

在数据集中,单个样本通常指单列数据,单位范数指的是,向量的长度(范数)为1

3.1.1 normalize函数
def normalize(X, norm='l2', axis=1, copy=True, return_norm=False):
  • 参数说明
    • X :需要进行归一化的数组
    • norm :范式类型,默认为’l2’,即第二范式,可选’l1’,‘l2’,‘max’
    • axis :维度,默认为1,即表示行,若为0,则表示列
    • copy :略
    • return_norm :是否返回每个样本缩放的标准,boolean值,默认为False
  • 使用实例
X = [[1., -1.,  2.], [2.,  0.,  0.], [0.,  1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l1') # l1范式,每一行的绝对值之和为1
# out
# array([[0.25, -0.25,  0.5 ], [1.  ,  0.  ,  0.  ], [0.  ,  0.5 , -0.5 ]])
X_normalized = preprocessing.normalize(X, norm='l1', return_norm=True) # 返回缩放标准
# out
# (array([[ 0.25, -0.25,  0.5 ],[ 1.  ,  0.  ,  0.  ],[ 0.  ,  0.5 , -0.5 ]]),
#  array([4., 2., 2.]))
3.1.2 Normalizer 工具类

Normalizer 工具类通过使用 Transformer API实现了相同的归一化效果。但和其他转换器不一样的是,这个转换器没有状态,其fit函数并没有对转换保留状态的。

# Normalizer类中的fit函数
def fit(self, X, y=None):check_array(X, accept_sparse='csr')return self

fit函数只是对X进行数组校验,可见它并无状态,整个转换的过程,实际是全在 transform 函数

def transform(self, X, copy=None):copy = copy if copy is not None else self.copyX = check_array(X, accept_sparse='csr')return normalize(X, norm=self.norm, axis=1, copy=copy)

实际上,该类调用的依旧是normalize 函数。

值得一提的是,Normalizer 工具类和 normalize 函数都支持稀疏矩阵的输入,并会自动转化为压缩的稀疏行形式。

4. 类别特征编码

在机器学习中,特征经常不是连续的数值型的而是标称型的(categorical)。

标称型数据:一般在有限的数据中取,而且只存在‘是’和‘否’两种不同的结果,有时可能有多个结果,但也有限

为了将标称型数据转换为数值型数据,可以使用 OrdinalEncoder 工具类和 OneHotEncoder 工具类。

4.1 OrdinalEncoder类

def __init__(self, categories='auto', dtype=np.float64):
  • 实例
enc = preprocessing.OrdinalEncoder()
X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
enc.transform([['female', 'from US', 'uses Safari']])
# 此处fit保留了转码的状态,相当于保存了编码规范。

这样的整数特征表示并不能在scikit-learn的估计器中直接使用,因为这样的连续输入,估计器会认为类别之间是有序的,但实际却是无序的。

4.2 OneHotEncoder类

def __init__(self, n_values=None, categorical_features=None,categories=None, drop=None, sparse=True, dtype=np.float64,handle_unknown='error'):
enc = preprocessing.OneHotEncoder()
X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
enc.transform([['female', 'from US', 'uses Safari'], ['male', 'from Europe', 'uses Safari']]).toarray()
# out 
# array([[1., 0., 0., 1., 0., 1.],
#       [0., 1., 1., 0., 0., 1.]])

此时可通过enc.categories_参数导出数组的维数,当然可以手动设置categories参数

genders = ['female', 'male']
locations = ['from Africa', 'from Asia', 'from Europe', 'from US']
browsers = ['uses Chrome', 'uses Firefox', 'uses IE', 'uses Safari']
enc = preprocessing.OneHotEncoder(categories=[genders, locations, browsers])
X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
enc.transform([['female', 'from Asia', 'uses Chrome']]).toarray()
# array([[1., 0., 0., 1., 0., 0., 1., 0., 0., 0.]])

OneHotEncoder 类的作用在于对所有的特征进行一个占位操作,做一个假设,假设有以上10个特征,即genders、locations、browsers指定的特征,共有10个。此时对这十个特征进行排序(并不需要保证同一类别的特征放在相邻位置),例如,我们排列顺序如下(实际上fix函数的真正功能只是根据X的数据对以上10个特征进行某种排序):
在这里插入图片描述
将数据排序之后,我们假设一个样本 [‘female’, ‘from Asia’, ‘uses Chrome’] ,可见,里面出现的特征在上列序列中的第1,4,7位,则我们可以把该样本编码为 [1,0,0,1,0,0,1,0,0,0] ,即在一个长度为10的0向量对应位置设为1。

5 离散化

离散化 (Discretization) (有些时候叫 量化(quantization) 或 装箱(binning)) 提供了将连续特征划分为离散特征值的方法。其目的就是把具有连续属性的数据集变换成只有名义属性(nominal attributes)的数据集。

5.1 KBinsDiscretizer

  • 类定义
def __init__(self, n_bins=5, encode='onehot', strategy='quantile'):
  • 参数说明
参数参数类型可选值含义默认值
n_binsint或arrayint或array每个特征中分箱的个数5
encodestr‘onehot’, ‘onehot-dense’, ‘ordinal’编码方式’onehot‘
strategystr‘uniform’,‘quantile’,‘strategy’分箱的宽度‘quantile’

encode参数中包含三个可选值:

onehot’:做哑变量,之后返回一个稀疏矩阵,每一列是一个特征的类别,含有该类别的样本表示为1,否则为0.

onehot-dense’:做哑变量,之后返回一个密集数组

ordinal’:每个特征的每个箱都被编码为一个整数,返回每一列是一个特征,每个特征下含有不同整数编码的箱的矩阵。

strategy参数中含有三个可选值:

uniform’:等宽分箱,每个特征中每个箱的最大值之间的差为(Feature.max-Feature.min)/n_bins

quantile’:等位分箱,每个特征中每个箱内的样本数量一致

strategy’:按聚类分箱,每个箱中的值到最近的一维k均值聚类的簇心的距离都相同

5.2 特征二值化

特征二值化 是将数值特征用阈值过滤得到布尔值的过程,可以通过binarize 函数实现

def binarize(X, threshold=0.0, copy=True): # 传入一个数据集,并可设定阈阈值(默认为0)

函数实现:

X = check_array(X, accept_sparse=['csr', 'csc'], copy=copy)
if sparse.issparse(X):if threshold < 0:raise ValueError('Cannot binarize a sparse matrix with threshold < 0')cond = X.data > thresholdnot_cond = np.logical_not(cond)X.data[cond] = 1X.data[not_cond] = 0X.eliminate_zeros()
else:cond = X > thresholdnot_cond = np.logical_not(cond)X[cond] = 1X[not_cond] = 0return X

可见函数只是简单的对数据集中中小于阈值与大于阈值的值进行一个划分。

Binarizer 类也可实现该功能,但其fit函数并无实际作用,只是在transform中调用了binarize 函数实现:

return binarize(X, threshold=self.threshold, copy=copy)

6. 生产多项式特征

增加一些输入数据的非线性特征来增加模型的复杂度,最直接的办法是给数据添加多项式特征。可通过 PolynomialFeatures 实现方式:

  • 类定义:
def __init__(self, degree=2, interaction_only=False, include_bias=True, order='C'):
  • 参数说明:

    • degree :多项式的维度,默认为2,当设定为2时,若一个样本为[x1,x2],则转换后的样本变为[1,x1,x2,x12,x1x2,x22]
    • interaction_only 如果为真,则只返回相互作用的特征值,例如,对于上例,返回样本是[1,x1,x2,x1x2],默认为False
    • include_bias :如果为True(默认),则包括偏置列,其中所有多项式幂为零的特征(即一列1 - 充当线性模型中的截距项)
    • order :密集情况下的输出数组的顺序。'F’顺序计算速度更快,但可能会降低后续估算器的速度,默认为C,可选[‘C’, ‘F’]
  • 实例

X = np.arange(6).reshape(3, 2)
X
# out:
X
# array([[0, 1],
#        [2, 3],
#        [4, 5]])
poly = PolynomialFeatures(2)
poly.fit_transform(X)
# out:
# array([[ 1.,  0.,  1.,  0.,  0.,  1.],
#        [ 1.,  2.,  3.,  4.,  6.,  9.],
#        [ 1.,  4.,  5., 16., 20., 25.]])

当使用多项的 Kernel functions 时 ,多项式特征被隐式地在核函数中被调用(比如, sklearn.svm.SVC , sklearn.decomposition.KernelPCA)

7. 自定义转换器

想要将一个已有的 Python 函数转化为一个转换器来协助数据清理或处理。可以使用 FunctionTransformer 从任意函数中实现一个转换器

以下有一个自定义函数,功能是返回数组第一行:

def my_function(X):return X[0]

接下来用其来构造一个自定义的转换器:

X = np.array([[0, 1], [2, 3]]) # 模拟数据
transformer = FunctionTransformer(my_function, validate=True)
transformer.transform(X)

结果:

array([0, 1])

http://chatgpt.dhexx.cn/article/0iRHTj6d.shtml

相关文章

javaScript学习笔记【尚硅谷】

javaScript学习笔记【尚硅谷】 这是我在看尚硅谷的前端大神超哥视频时&#xff0c;所记录的笔记&#xff01; 文章目录 javaScript学习笔记【尚硅谷】[TOC](文章目录)1、javaScript基本知识1.2、JS编写位置1.3、JS基本语法1.4、变量与字面量1.5、标识符1.6、数据类型1.6.1、Nu…

机器学习流程及详细内容(1)

一般流程&#xff1a;数据收集、整理→数据预处理与特征工程&#xff08;数据清理、集成、规约、变换、特征提取、筛选&#xff09;→模型的选择与建立→模型的评估与优化。 数据收集 既可以使用公开的数据集&#xff0c;也可通过爬虫、购买或者实时数据的方式自己收集。 UC…

机器学习(Machine Learning)与深度学习(Deep Learning)资料汇总

《Brief History of Machine Learning》 介绍:这是一篇介绍机器学习历史的文章&#xff0c;介绍很全面&#xff0c;从感知机、神经网络、决策树、SVM、Adaboost到随机森林、Deep Learning. 《Deep Learning in Neural Networks: An Overview》 介绍:这是瑞士人工智能实验室Jurg…

Flutter 学习

Flutter 学习 参照&#xff1a;https://book.flutterchina.club/ 参照&#xff1a;https://flutter.cn/docs/development/platform-integration/platform-channels?tabtype-mappings-java-tab 目前进度&#xff1a;https://book.flutterchina.club/chapter9/animated_widgets…

原生开发如何学习 Flutter | 谷歌社区说

Hello 大家好&#xff0c;我是《Flutter 开发实战详解》的作者&#xff0c;Github GSY 系列开源项目的负责人郭树煜&#xff0c;目前开源的 gsy_github_app_flutter 以 13k 的 star 在中文总榜的 dart 排行上暂处第一名。 数据来源&#xff1a; https://github.com/GrowingGit/…

【CVRP】基于matlab遗传算法求解带容量的车辆路径规划问题【含Matlab源码 162期】

⛄一、VRP简介 车辆路径问题&#xff08;VRP&#xff09;最早是由 Dantzig 和 Ramser 于1959年首次提出&#xff0c;它是指一定数量的客户&#xff0c;各自有不同数量的货物需求&#xff0c;配送中心向客户提供货物&#xff0c;由一个车队负责分送货物&#xff0c;组织适当的行…

matlab解决LRP类型的多配送中心路径优化问题

** 问题描述 ** 有关多配送中心的选址-路径优化问题&#xff0c;一般是通过基于区域内的客户需要求&#xff0c;对配送中心进行合理的选址以及配送中心的车辆调度以及路径优化。在给出的配送中心候选点位置已知&#xff0c;需要在给出的这些位置中&#xff0c;通过与顾客需求…

<代码分享> 一种无人机配合卡车配送的车辆路径规划模型

本文为本人博客《一种无人机配合卡车配送的车辆路径规划模型》的代码分享。 由于近期此文的关注者较多&#xff0c;代码分享较为不便&#xff0c;因此决定专门写一篇博客以提供源码。 感谢各位博友关注&#xff0c;本人能力有限&#xff0c;如有错误&#xff0c;还请及时批评指…

(附源码)springboot车辆管理系统 毕业设计031034

车辆管理系统的设计与实现 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&…

QT+SQL Server实现车辆管理系统 -代码具体实现

QTSQL Server 实现车辆管理系统 -代码具体实现 1.摘要2.整体框架3.具体代码实现3.1 连接数据库3.2 登录操作3.3 申请账户3.4 添加车辆信息3.5 查询车辆信息3.6删除车辆信息3.7修改车辆信息3.8 添加司机信息 4.总结5.资源下载链接 1.摘要 前面一篇文章简要介绍了车辆管理系统的…

如何使用低代码进行车队管理?

处理任何业务都具有挑战性&#xff0c;但车队管理无疑是所有业务中的佼佼者。无论是司机短缺、环境问题、国际法规还是行业不稳定&#xff0c;车队经理都必须面对这一切。除此之外&#xff0c;还有数字化和路线优化的概念。数字化转型车队管理业务意味着消除挑战&#xff0c;拥…

车辆自然驾驶轨迹数据集/交通流数据介绍

文章目录 NGSIMNGSIM 概览快速路车道选择算法Interstate 80 Freeway 数据集Lankershim Boulevard 数据集US highway101数据集动态交通分配DTACORSIM Argoverse Motion Forecasting DatasetAIMSUNHighDITS DataHub 美国智能交通数据库Data.govPeMSPortland Oregon Region data英…

3D车辆检测AP评价指标代码的理解

课题研究的是单目3D车辆的识别&#xff0c;采用的目标检测网络是SMOKE&#xff0c;为了可以更好的定量评测训练模型的性能&#xff0c;需要使用到合理的评测指标&#xff0c;目前比较流行的评测指标是得到多组precision和recall值画出PR曲线&#xff0c;然后计算PR曲线下的面积…

根据车辆型号自动生成车辆编号

开发工具与关键技术&#xff1a;Visual Studio 2015 linq 正则 作者&#xff1a;孙水兵 撰写时间&#xff1a;2019年6月26一、 功能 根据不同的类型的车辆型号&#xff0c;生成以车辆型号开头的车辆编号。 二、 达到的效果 用户选择了车辆型号之后&#xff0c;将对应的车辆编…

【路径规划】基于遗传算法求解多车多类型车辆的车辆路径优化问题附matlab代码

1 内容介绍 多车辆多路线的交通路线优化涉及到排序问题,是一个N-P难题,高效精确的算法存在的可能性不大.提出了基于遗传算法的求解方法,给出了实例来证明如何利用遗传算法解决多车辆多路线的优化问题.结果证明,一般情况下利用遗传算法对于多车辆多路线的行车路线优化能得到一组…

机动车登记信息代码

原链接&#xff1a;机动车登记信息代 搜索结果本栏目用于收集和整理行业相关标准&#xff0c;如机械行业&#xff0c;化工行业等。http://www.gb99.cn/e/search/result/?searchid76243针对其中第七项车辆信息牌照代码如下&#xff1a;

利用低代码平台进行车辆管理,为交通行业添砖加瓦

概要&#xff1a;本文介绍了交通行业车辆管理的重要性&#xff0c;并详细阐述了基于低代码平台设计的车辆管理系统的优势。通过快速开发、易于维护、增加灵活性、提高数据可靠性、降低成本以及实时监控等多个方面&#xff0c;这种车辆管理系统可以帮助企业提高效率和降低成本&a…

(c++课程设计)简单车辆管理系统(有五种类型的车辆)代码+报告

关于这个课程设计 &#xff0c;差点没把我头发愁没。 好了其实本质还是东拼西凑&#xff0c;编程能力没怎么长进&#xff0c;花里胡哨的东西却学了不少&#xff08;不是&#xff09; 万恶的学院&#xff0c;虽然要求三人一组&#xff0c;但是却分一二三类&#xff0c;三个人代…

什么是车辆识别代码(VIN)

车辆识别代码(VIN),VIN是英文Vehicle Identification Number(车辆识别码)的缩写。因为ASE标准规定:VIN码由17位字符组成,所以俗称十七位码。正确解读VIN码,对于我们正确地识别车型,以致进行正确地诊断和维修都是十分重要的。车辆识别代码根据国家车辆管理标准确定,包…

Eigen学习笔记1:在VS2015下Eigen(矩阵变换)的配置

一、Eigen简介 Eigen是一个高层次的C 库&#xff0c;有效支持线性代数&#xff0c;矩阵和矢量运算&#xff0c;数值分析及其相关的算法。 Eigen适用范围广&#xff0c;支持包括固定大小、任意大小的所有矩阵操作&#xff0c;甚至是稀疏矩阵&#xff1b;支持所有标准的数值类型&…