特征预处理–长尾分布的处理方案

特征预处理–长尾分布的处理方案声明 版权所有 转载请联系作者并注明出处 http blog csdn net u0 viewmode contents0x00 前言数据预处理包含数据探索 数据清洗和特征预处理三部分 特征工程系列 特征预处理 上 介绍了无量纲化和特征分桶相关的处理方法 本章将继续介绍特征预处理中的统计变换和类别特征编码相关内容 0x01 统计变换数据分布的倾斜

声明:版权所有,转载请联系作者并注明出处  http://blog.csdn.net/u0?viewmode=contents

log变换的论文:http://snap.stanford.edu/class/cs224w-readings/goel10longtail.pdf

0x00 前言

数据预处理包含数据探索、数据清洗和特征预处理三部分,《特征工程系列:特征预处理(上)》介绍了无量纲化和特征分桶相关的处理方法,本章将继续介绍特征预处理中的统计变换和类别特征编码相关内容。

特征预处理--长尾分布的处理方案

0x01 统计变换

数据分布的倾斜有很多负面的影响。我们可以使用特征工程技巧,利用统计或数学变换来减轻数据分布倾斜的影响。使原本密集的区间的值尽可能的分散,原本分散的区间的值尽量的聚合。

这些变换函数都属于幂变换函数簇,通常用来创建单调的数据变换。它们的主要作用在于它能帮助稳定方差,始终保持分布接近于正态分布并使得数据与分布的平均值无关。

1.Log变换

1)定义

Log变换通常用来创建单调的数据变换。它的主要作用在于帮助稳定方差,始终保持分布接近于正态分布并使得数据与分布的平均值无关。

Log 变换属于幂变换函数簇。该函数用数学表达式表示为

特征预处理--长尾分布的处理方案

自然对数使用 b=e,e=2.71828,通常叫作欧拉常数。你可以使用通常在十进制系统中使用的 b=10 作为底数。

当应用于倾斜分布时 Log 变换是很有用的,因为Log变换倾向于拉伸那些落在较低的幅度范围内自变量值的范围,倾向于压缩或减少更高幅度范围内的自变量值的范围。从而使得倾斜分布尽可能的接近正态分布。  

2)作用

针对一些数值连续特征的方差不稳定,特征值重尾分布我们需要采用Log化来调整整个数据分布的方差,属于方差稳定型数据转换。比如在词频统计中,有些介词的出现数量远远高于其他词,这种词频分布的特征就会现有些词频特征值极不协调的状况,拉大了整个数据分布的方差。这个时候,可以考虑Log化。尤其在分本分析领域,时间序列分析领域,Log化非常常见, 其目标是让方差稳定,把目标关注在其波动之上。

3)变换效果

特征预处理--长尾分布的处理方案

4)实现代码

fcc_survey_df['Income_log'] = np.log((1+fcc_survey_df['Income']))

2.Box-Cox变换

1)定义

Box-Cox 变换是另一个流行的幂变换函数簇中的一个函数。该函数有一个前提条件,即数值型值必须先变换为正数(与 log 变换所要求的一样)。万一出现数值是负的,使用一个常数对数值进行偏移是有帮助的。

Box-Cox 变换函数:

特征预处理--长尾分布的处理方案

生成的变换后的输出y是输入 x 和变换参数的函数;当 λ=0 时,该变换就是自然对数 log 变换,前面我们已经提到过了。λ 的最佳取值通常由最大似然或最大对数似然确定。

2)作用

Box-Cox变换是Box和Cox在1964年提出的一种广义幂变换方法,是统计建模中常用的一种数据变换,用于连续的响应变量不满足正态分布的情况。Box-Cox变换之后,可以一定程度上减小不可观测的误差和预测变量的相关性。Box-Cox变换的主要特点是引入一个参数,通过数据本身估计该参数进而确定应采取的数据变换形式,Box-Cox变换可以明显地改善数据的正态性、对称性和方差相等性,对许多实际数据都是行之有效的。

3)变化效果

特征预处理--长尾分布的处理方案

 

4)实现代码

import scipy.stats as spstats # 从数据分布中移除非零值 income = np.array(fcc_survey_df['Income']) income_clean = income[~np.isnan(income)] # 计算最佳λ值 l, opt_lambda = spstats.boxcox(income_clean) print('Optimal lambda value:', opt_lambda) # 进行Box-Cox变换 fcc_survey_df['Income_boxcox_lambda_opt'] = spstats.boxcox(fcc_survey_df['Income'],lmbda=opt_lambda)

0x02 分类特征(类别特征)编码

在统计学中,分类特征是可以采用有限且通常固定数量的可能值之一的变量,基于某些定性属性将每个个体或其他观察单元分配给特定组或名义类别。

1.标签编码(LabelEncode)

1)定义

LabelEncoder是对不连续的数字或者文本进行编号,编码值介于0和n_classes-1之间的标签。

2)优缺点

优点:相对于OneHot编码,LabelEncoder编码占用内存空间小,并且支持文本特征编码。

缺点:它隐含了一个假设:不同的类别之间,存在一种顺序关系。在具体的代码实现里,LabelEncoder会对定性特征列中的所有独特数据进行一次排序,从而得出从原始输入到整数的映射。所以目前还没有发现标签编码的广泛使用,一般在树模型中可以使用。
例如:比如有[dog,cat,dog,mouse,cat],我们把其转换为[1,2,1,3,2]。这里就产生了一个奇怪的现象:dog和mouse的平均值是cat。

3)实现代码

from sklearn.preprocessing import LabelEncoder le = LabelEncoder() le.fit(["paris", "paris", "tokyo", "amsterdam"]) print('特征:{}'.format(list(le.classes_))) # 输出 特征:['amsterdam', 'paris', 'tokyo'] print('转换标签值:{}'.format(le.transform(["tokyo", "tokyo", "paris"]))) # 输出 转换标签值:array([2, 2, 1]...) print('特征标签值反转:{}'.format(list(le.inverse_transform([2, 2, 1])))) # 输出 特征标签值反转:['tokyo', 'tokyo', 'paris']

2.独热编码(OneHotEncode)

1)定义

OneHotEncoder用于将表示分类的数据扩维。最简单的理解就是与位图类似,设置一个个数与类型数量相同的全0数组,每一位对应一个类型,如该位为1,该数字表示该类型。

OneHotEncode只能对数值型变量二值化,无法直接对字符串型的类别变量编码。

2)为什么要使用独热编码

独热编码是因为大部分算法是基于向量空间中的度量来进行计算的,为了使非偏序关系的变量取值不具有偏序性,并且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。  

为什么特征向量要映射到欧式空间?
将离散特征通过one-hot编码映射到欧式空间,是因为,在回归、分类、聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算。

3)例子

假如有三种颜色特征:红、黄、蓝。

在利用机器学习的算法时一般需要进行向量化或者数字化。那么你可能想令 红=1,黄=2,蓝=3。那么这样其实实现了标签编码,即给不同类别以标签。然而这意味着机器可能会学习到“红
<黄<蓝”,但这并不是我们的让机器学习的本意,只是想让机器区分它们,并无大小比较之意。< p="">

所以这时标签编码是不够的,需要进一步转换。因为有三种颜色状态,所以就有3个比特。即红色:1 0 0 ,黄色: 0 1 0,蓝色:0 0 1 。如此一来每两个向量之间的距离都是根号2,在向量空间距离都相等,所以这样不会出现偏序性,基本不会影响基于向量空间度量算法的效果。

4)优缺点

优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。

缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。

5)实现代码

from sklearn.preprocessing import OneHotEncoder enc = OneHotEncoder() enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) # fit来学习编码 enc.transform([[0, 1, 3]]).toarray() # 进行编码 # 输出:array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])

使用pandas实现

import pandas as pd import numpy as np sex_list = ['MALE', 'FEMALE', np.NaN, 'FEMALE', ] df = pd.DataFrame({'SEX': sex_list}) display(df) # 输出 SEX 0 MALE 1 FEMALE 2 NaN 3 FEMALE df = pd.get_dummies(df['SEX'],prefix='IS_SEX') display(df) # 输出 IS_SEX_FEMALE IS_SEX_MALE 0 0 1 1 1 0 2 0 0 3 1 0

3.标签二值化(LabelBinarizer)

1)定义

功能与OneHotEncoder一样,但是OneHotEncode只能对数值型变量二值化,无法直接对字符串型的类别变量编码,而LabelBinarizer可以直接对字符型变量二值化。

2)实现代码

from sklearn.preprocessing import LabelBinarizer lb = LabelBinarizer() lb.fit([1, 2, 6, 4, 2]) print(lb.classes_) # 输出 array([1, 2, 4, 6]) print(lb.transform([1, 6])) # 输出 array([[1, 0, 0, 0], [0, 0, 0, 1]]) print(lb.fit_transform(['yes', 'no', 'no', 'yes'])) # 输出 array([[1], [0], [0], [1]])

4.多标签二值化(MultiLabelBinarizer)

1)定义

用于label encoding,生成一个(n_examples * n_classes)大小的0~1矩阵,每个样本可能对应多个label。

2)适用情况

  • 每个特征中有多个文本单词;

    ”健身 电影 音乐”)适合使用多标签二值化,因为每个用户可以同时存在多种兴趣爱好。

  • 多分类类别值编码的情况。

    [action, horror]和[romance, commedy])需要先进行多标签二值化,然后使用二值化后的值作为训练数据的标签值。

3)实现代码

from sklearn.preprocessing import MultiLabelBinarizer mlb = MultiLabelBinarizer() print(mlb.fit_transform([(1, 2), (3,)])) # 输出 array([[1, 1, 0], [0, 0, 1]]) print(mlb.classes_) # 输出:array([1, 2, 3]) print(mlb.fit_transform([{'sci-fi', 'thriller'}, {'comedy'}])) # 输出:array([[0, 1, 1], [1, 0, 0]]) print(list(mlb.classes_)) # 输出:['comedy', 'sci-fi', 'thriller']

5.平均数编码(Mean Encoding)

1)定义

平均数编码(mean encoding),针对高基数类别特征的有监督编码。当一个类别特征列包括了极多不同类别时(如家庭地址,动辄上万)时,可以采用。

平均数编码(mean encoding)的编码方法,在贝叶斯的架构下,利用所要预测的应变量(target variable),有监督地确定最适合这个定性特征的编码方式。在Kaggle的数据竞赛中,这也是一种常见的提高分数的手段。

算法原理详情可参考:平均数编码:针对高基数定性特征(类别特征)的数据预处理/特征工程。

2)为什么要用平均数编码

如果某一个特征是定性的(categorical),而这个特征的可能值非常多(高基数),那么平均数编码(mean encoding)是一种高效的编码方式。在实际应用中,这类特征工程能极大提升模型的性能。

因为定性特征表示某个数据属于一个特定的类别,所以在数值上,定性特征值通常是从0到n的离散整数。例子:花瓣的颜色(红、黄、蓝)、性别(男、女)、地址、某一列特征是否存在缺失值(这种NA 指示列常常会提供有效的额外信息)。

一般情况下,针对定性特征,我们只需要使用sklearn的OneHotEncoder或LabelEncoder进行编码,这类简单的预处理能够满足大多数数据挖掘算法的需求。定性特征的基数(cardinality)指的是这个定性特征所有可能的不同值的数量。在高基数(high cardinality)的定性特征面前,这些数据预处理的方法往往得不到令人满意的结果。

3)优点

和独热编码相比,节省内存、减少算法计算时间、有效增强模型表现。

4)实现代码

MeanEnocodeFeature = ['item_city_id','item_brand_id'] #声明需要平均数编码的特征 ME = MeanEncoder(MeanEnocodeFeature) #声明平均数编码的类 trans_train = ME.fit_transform(X,y)#对训练数据集的X和y进行拟合 test_trans = ME.transform(X_test)#对测试集进行编码

MeanEncoder实现源码详情可参考:平均数编码:针对高基数定性特征(类别特征)的数据预处理/特征工程。

0x0FF 总结

  1. 特征预处理是数据预处理过程的重要步骤,是对数据的一个的标准的处理,几乎所有的数据处理过程都会涉及该步骤。
  2. 由于树模型(Random Forest、GBDT、xgboost等)对特征数值幅度不敏感,可以不进行无量纲化和统计变换处理;

    同时,由于树模型依赖于样本距离来进行学习,所以也可以不进行类别特征编码(但字符型特征不能直接作为输入,所以需要至少要进行标签编码)。

  3. 依赖样本距离来学习的模型(如线性回归、SVM、深度学习等)
    • 对于数值型特征需要进行无量纲化处理;
    • 对于一些长尾分布的数据特征,可以做统计变换,使得模型能更好优化;
    • 对于线性模型,特征分箱可以提升模型表达能力;
  4. 对数值型特征进行特征分箱可以让模型对异常数据有很强的鲁棒性,模型也会更稳定。

    另外,分箱后需要进行特征编码。

如有错误欢迎指正~

参考文献

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220435.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午8:29
下一篇 2026年3月17日 下午8:29


相关推荐

  • 自己搭建个人文件服务器_内网设置微信代理

    自己搭建个人文件服务器_内网设置微信代理背景:因为微信公众平台支持的后台服务器只允许为80端口,而本地服务器开发程序与在VPS上部署程序运行,每次无论是使用scp还是ftp进行文件传输无疑是低效的,因此需要一种方法可以方便的在本地服务器调试微信公众平台。有的使用,ngrok,此方法是通过ssh反向代理达到目的。1.在本地服务器通过命令:ssh–fNR8181:localhost:80user@host.com–p22–g达到…

    2022年8月21日
    11
  • 词袋模型(BOW)

    词袋模型(BOW)做自然语言处理 第一步肯定是数据的预处理了 对于图像数据 我们可以把图像转化为矩阵 那么对于自然语言 我们又应该进行怎样的转化呢 方法有很多 在网上一搜 会发现 word2vec 分布式表示 wordembeddin 等等一大堆名次 但是可以说 他们都是为了让文本能够以数字的形式呈现 要么是一维向量 要么是矩阵等等 不同的方法模型有不同的优缺点 这里先从比较简单的方法说起 也就是本文的主角词袋

    2026年3月18日
    3
  • labview车牌识别教学视频(车牌识别)

    OCR从本质上可看作是目标分类和识别的一种实际应用,因此它也包括训练和分类过程。

    2022年4月13日
    64
  • python爬虫学习教程,短短25行代码批量下载豆瓣妹子图片

    python爬虫学习教程,短短25行代码批量下载豆瓣妹子图片python爬虫学习教程,短短25行代码批量下载豆瓣妹子图片、非常简短,代码不是很多非常适合新手练习!学习python、python爬虫过程中有不懂的可以加入我的python零基础系统学习交流秋秋qun:前面是934,中间109,后面是170,与你分享Python企业当下人才需求及怎么从零基础学习Python,和学习什么内容。相关学习视频资料、开发工具都有分享!代码展示:#!/u…

    2025年11月17日
    3
  • php arcsin函数,excel如何计算反三角函数

    excel如何计算反三角函数Excel中计算反三角函数需要用到反余弦函数(ACOS)、反正弦函数(ASIN)和反正切函数(ATAN)。函数ACOS是用来计算指定数值的反余弦值的,公式为:=ACOS(number)。函数ASIN是用来计算指定数值的反正弦值的,公式为:=ASIN(number)。函数ATAN是用来计算指定数值的反正切值的,公式为:=ATAN(number)。反余弦函数的使用1、反余弦…

    2022年4月8日
    262
  • Python内置函数详解——总结篇

    Python内置函数详解——总结篇引言国庆期间下定决心打算学习Python,于是下载安装了开发环境。然后问题就来了,怎么开始呢?纠结一番,还是从官方帮助文档开始吧。可是全是英文啊,英语渣怎么破?那就边翻译边看边实践着做吧(顺便吐槽

    2022年7月5日
    22

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号