Python数据分析之特征处理笔记三——特征预处理(特征选择)

这篇具有很好参考价值的文章主要介绍了Python数据分析之特征处理笔记三——特征预处理(特征选择)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

书接上文,进行数据清洗过程后,我们得到了没有空值、异常值、错误值的数据,但想要用海量的数据来建立我们所需要的算法模型,仅仅是数据清洗的过程是不够的,因为有的数据类型是数值,有的是字符,怎样将不同类型的数据联系起来?以及在保证最大化信息量的前提下,怎样得到便于分析的数据?这就是特征预处理要做的工作。

一、理论基础

1. 基本概念

特征预处理是数据预处理过程的重要步骤,是对数据的一个的标准的处理,几乎所有的数据处理过程都会涉及该步骤。在进行特征预处理之前需要确定标注,即标签(label)。标注的选择主要与我们的目的相契合,比如要探究不同种族、不同地区的人们长寿是否与性别相关,那么性别就可以作为标注来表明我们的目的。

2. 一般步骤

2.1 特征选择

目标是寻找最优特征子集。特征选择能剔除与标注不相关(irrelevant)或冗余(redundant )的特征,从而达到减少特征个数,提高模型精确度,减少运行时间的目的。另一方面,选取出真正相关的特征简化模型,协助理解数据产生的过程。

之所以要考虑特征选择,是因为机器学习经常面临过拟合的问题。 过拟合的表现是模型参数太贴合训练集以及验证集数据,在训练集上效果很好而在测试集上表现不好。简言之模型的泛化能力差。过拟合的原因是模型对于训练集数据来说太复杂,要解决过拟合问题,一般考虑用特征选择的方法对数据进行降维。

特征选择的思想主要有三种:

  • 过滤思想:在n个特征中,对每个特征 x(i),分别计算 x(i) 相对于标注 y 的信息量 S(i) ,得到 n 个结果。然后将 n 个 S(i) 按照从大到小排序,输出前 k 个特征。显然,这样数据的复杂度大大降低。那么关键的问题就是使用什么样的方法来度量 S(i) ,我们的目标是选取与 y 关联最密切的一些 特征x(i)。
  • 包裹思想:基于留出法(hold-out),将特征全集X划分为两个互斥的集合,其中一个集合作为训练集S,另外一个作为测试集T,即X=S∪T,S∩T=0。在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的评估。将训练集根据特征子集选择方法选出特征子集,对于每一个待选的特征子集,都在训练集上训练一遍模型,然后在测试集上根据误差大小选择出特征子集。需要先选定特定算法,通常选用普遍效果较好的算法, 例如Random Forest, SVM, kNN等等。
  • 嵌入思想:先使用某些机器学习的简单回归模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征(采用这个方法有比较大的风险,要慎重选择用哪个回归模型)。

2.1.1 过滤思想

 2.1.1.1 皮尔逊(pearson)相关系数

特征选择与提取最全总结之过滤法 - 腾讯云开发者社区-腾讯云 (tencent.com)

相关系数是衡量特征与标注相关性最直接简单的方法,取值范围在[-1,1],当相关系数接近或等于0时,说明该特征与标注的相关性很小或不相关。皮尔逊相关系数可以用来探究任何数据类型之间的相关性,即使有离散非二值的数据,经过定序处理后也可用相关系数的方法。

以下代码为相关系数的输出,若要遍历特征全集根据相关系数筛选特征,还需要通过函数或方程等方法遍历全集。

import pandas as pd
s1=pd.Series([0.1,0.2,1.1,2.4,1.3,0.3,0.5])
s2=pd.Series([0.5,0.4,1.2,2.5,1.1,0.7,0.1])
s1.corr(s2,method='pearson ') #输出s1、s2之间的相关系数

Python数据分析之特征处理笔记三——特征预处理(特征选择)

Pearson相关系数的一个明显缺陷是,它只对线性关系敏感。如果关系是非线性的,即便两个变量具有一一对应的关系,Pearson相关性也可能会接近 0 。 

  2.1.1.2 卡方检验

卡方检验用在属性相关性检验上,一般所探查的数据类型为类别性数据。卡方检验的本质是推测两组数据之间的差异,其检验的原假设是”两组数据是相互独立的”。卡方检验返回卡方值和P值两个统计量,其中卡方值很难界定有效的范围,而p值,我们一般使用0.01或0.05作为显著性水平,即p值判断的边界。卡方检验的具体介绍见:

卡方检验_百度百科 (baidu.com)

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest #常用的特征选择的函数
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target  #iris数据集,y取值有0,1,2,为标签化数据
#选择K=2个最好的特征,返回选择特征后的数据
X_new = SelectKBest(chi2, k=2).fit_transform(X, y) #chi2为指定检验为卡方检验

先看X的前5行数据

X[0:5,:]

Python数据分析之特征处理笔记三——特征预处理(特征选择)

 y的前5行数据

y[:5]

Python数据分析之特征处理笔记三——特征预处理(特征选择)

 最后提取出的新特征的前5行,可以看到结果为提取X的最后两列特征。

Python数据分析之特征处理笔记三——特征预处理(特征选择)

  2.1.1.3 互信息(熵增益)和最大信息系数

互信息法是用来捕捉每个特征与标注之间的任意关系(包括线性和非线性关系)的过滤方法,适用于特征和标注都是离散二值的研究。互信息从字面上理解为相互包含的信息,互信息法不返回p值或F值类似的统计量,它返回“每个特征与标注之间的互信息量的估计”,这个估计量在[0,1]之间取值,为0则表示两个变量独立,为1则表示两个变量完全相关。互信息的计算公式为:

其中:H()表示求熵,例如:

关于熵的定义在此不再赘述,不理解的话可去搜一下资料。

想把互信息直接用于特征选择其实不是太方便:

  1. 它不属于度量方式,也没有办法归一化,在不同数据及上的结果无法做比较
  2. 对于连续变量的计算不是很方便,通常变量需要先离散化,而互信息的结果对离散化的方式很敏感。

最大信息系数(MIC)克服了这两个问题。它首先寻找一种最优的离散化方式,然后把互信息取值转换成一种度量方式,取值区间在 [0,1] 。minepy提供了MIC功能。

简单来说,最大信息系数就是将两个变量在二维空间中进行离散化处理,然后将二维空间按照行列数规定分成一定数量的区间块,并计算这些区间块的互信息,这就是一种分割下的互信息值。接着计算按照其他分割方法下的区块的互信息值,最后在这些互信息中选出最大的一个互信息进行归一化处理后(除以log(最小互信息))得到的就是最大信息系数。python中有包可以直接计算MIC,这是另外一位博主的代码,仅供参考:

from minepy import MINE

m = MINE()
x = np.random.uniform(-1, 1, 10000) #创建10000个取值在-1到1之间的随机数
m.compute_score(x, x**2) #取x的平方
print(m.mic())


from sklearn.feature_selection import SelectKBest
#由于MINE的设计不是函数式的,定义mic方法将其为函数式的,返回一个二元组,二元组的第2项设置成固定的P值0.5
def mic(x, y):
    m = MINE()
    m.compute_score(x, y)
    return (m.mic(), 0.5)
# 选择K个最好的特征,返回特征选择后的数据
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T,k=2).fit_transform(iris.data, iris.target)

 2.1.1.4 方差选择法

过滤特征选择法还有一种方法不需要度量特征 x(i) 和标注Y的信息量。这种方法先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。这是因为方差越大,该特征所包含的信息量越多,对于标注有着更强的解释含义。

VarianceThreshold是特征选择的简单基线方法。可以删除方差超过某个阈值的所有特征。默认情况下,它会删除所有零差异特征,即所有样本中具有相同值的特征。代码如下:

from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]] 
# 假设X是特征全集中的三个离散二值特征子集
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
# 方差选择法,返回值为特征选择后的数据
# 参数threshold为方差的阈值,因为二项分布的方差为p(1-p),则上面代码表示当方差超过(.8 * (1 - .8)时删除特征
print(sel.fit_transform(X))

返回结果为第二、第三列。

2.1.2 包裹思想

 2.1.2.1 向前搜索

基本思想为:最初时创建一个空的集合F,在n个特征子集选出一个特征子集加入到F中,这时通过交叉验证来判断错误率,接着继续往F集合中加入特征子集计算错误率,循环上述过程直至获得n个错误率或达到我们设定的阈值,最后挑选出最小错误率的特征子集。

 2.1.2.2 向后搜索

与向前搜索往F集合里增加特征相反的是,向后搜索是刚开始时F集合就包含了若干个特征子集,得出错误率后,每次删除一个特征子集,直到达到阈值或集合为空,然后得到最小错误率的特征集合。

 2.1.2.3 递归特征消除法(RFE)

递归特征消除(RFE)就是通过递归地考虑越来越小的特征集来选择特征。首先,对初始特征集训练估计器,通过coef_属性或feature_importances_属性获得每个特征的重要性。然后,从当前的特征集中删除最不重要的特征。也就是说通过不断地建立模型,每一次删除掉差的特征,直至遍历所有的特征。这种方法的效果很依赖于我们所选择的模型,以上面iris数据集为例:

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

#递归特征消除法,返回特征选择后的数据
#参数estimator为基模型
#参数n_features_to_select为选择的特征个数
RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)

2.1.3 嵌入法

基本思想:建立简单的回归模型,常用的模型是基于树的预测模型(SelectFromModel),能够计算特征的重要程度。基于树的方法比较易于使用,因为他们对非线性关系的建模比较好,并且不需要太多的调试,但要注意过拟合问题。参考:打牛地的博客-CSDN博客_封装式特征选择

 2.1.3.1 带惩罚项的基模型

比如LR加入正则。通过L1正则项来选择特征:L1正则方法具有稀疏解的特性,因此天然具备特征选择的特性,但是要注意,L1没有选到的特征不代表不重要,原因是两个具有高相关性的特征可能只保留了一个,如果要确定哪个特征重要应再通过L2正则方法交叉检验。

from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
X.shape #查看X的规格,显示为150行4列
(150, 4)
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y) 
#penalty:{‘l1’, ‘l2’}, default=’l2’,正则化方法,默认为L1
#loss:{‘hinge’, ‘squared_hinge’}, default=’squared_hinge’,即hinge的平方
#dual:bool, default=True,Prefer dual=False when n_samples > n_features. 令样本数大于特征数
#C:float, default=1.0,正则化的强度与 C 成反比.
#max_iter:int, default=1000,要运行的最大迭代次数。
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape
(150,3) #返回三个特征

 2.1.3.2 树模型(随机森林、决策树)

训练能够对特征打分的预选模型:RandomForest和Logistic Regression等都能对模型的特征打分,通过打分获得相关性后再训练最终模型。代码以博主的文章为例:

 from sklearn.ensemble import ExtraTreesClassifier
 from sklearn.datasets import load_iris
 from sklearn.feature_selection import SelectFromModel
 iris = load_iris()
 X, y = iris.data, iris.target
 X.shape
 (150, 4)
 clf = ExtraTreesClassifier()
 clf = clf.fit(X, y)
 clf.feature_importances_  # 返回每个特征的重要性
 array([ 0.04...,  0.05...,  0.4...,  0.4...])
 model = SelectFromModel(clf, prefit=True)
 X_new = model.transform(X)
 X_new.shape               
 (150, 2)

2.1.4 编码操作

接下来用三个思想来分析一个简单的数据集

import numpy as np
import pandas as pd 
import scipy.stats as ss
df=pd.DataFrame({'A':ss.norm.rvs(size=10),'B':ss.norm.rvs(size=10),'C':ss.norm.rvs(size=10),'D':np.random.randint(low=0,high=2,size=10)})
#创建一个df数据集,其中A、B、C都是符合正态分布大小为10的随机数,D为取值为0到1、大小为10的整数。

from sklearn.svm import SVR #SVR为常用的回归模型包、回归器
from sklearn.tree import DecisionTreeRegressor #DecisionTreeRegressor为决策树回归器

X=df.loc[:,['A','B','C']] #将A、B、C设置为特征
Y=df.loc[:,['D']] #将D设置为标注

from sklearn.feature_selection import SelectKBest,RFE,SelectFromModel
#上面SelectKBest为过滤思想用到的特征选择包,RFE为包裹思想中的递归特征消除法,SelectFromModel为嵌入思想的模型选择包

#过滤思想
skb=SelectKBest(k=2) #从特征中选出两个特征
skb.fit(X,Y) #拟合模型,输出指定函数
skb.transform(X) #转化选择的两个特征

#包裹思想
rfe=RFE(estimator=SVR(kernel='linear'),n_features_to_select=2,step=1) 
#estimator为指定回归器,linear为线性回归,n_features_to_select=2表示选择两个特征,step=1表示每次删除一个特征
rfe.fit_transform(X,Y) #转化出选择的两个特征和标注

#嵌入思想
sfm=SelectFromModel(estimator=DecisionTreeRegressor(),threshold=0.1)
#threshold=0.1 表示重要性低于0.1时就删除特征
sfm.fit_transform(X,Y)

以上就是特征选择的基本方法和简单的代码操作,想要学习复杂度较高的代码的小伙伴可以去Sklearn的官网看看。其他内容待下回分解......

部分资料和代码来源于以下参考文献:

特征预处理 - 知乎 (zhihu.com)

机器学习 特征选择(Feature Selection)方法汇总 - 知乎 (zhihu.com)

数据分析3——预处理理论(特征工程、数据清洗、特征预处理)_啧啧啧@的博客-CSDN博客

机器学习 特征选择(过滤法 封装法 嵌入法)_打牛地的博客-CSDN博客_封装式特征选择

华为大佬用159小时讲完的Python数据分析-数据挖掘教程,整整600集,零基础快速入门 手把手教学,学完即可就业_哔哩哔哩_bilibili文章来源地址https://www.toymoban.com/news/detail-430964.html

到了这里,关于Python数据分析之特征处理笔记三——特征预处理(特征选择)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于Python的海量豆瓣电影、数据获取、数据预处理、数据分析、可视化、大屏设计项目(含数据库)

    项目介绍 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主!!!!!!!!!! 本文基于Python的网络爬虫手段对豆瓣电影网站进行数据的抓取,通过合理的分析豆瓣网站的网页结构,并设计出规则来获取电影数据的JSON数据包,采用正态分布的延时措施

    2024年02月12日
    浏览(62)
  • 数据分析--数据预处理

    本文主要是个人的学习笔记总结,数据预处理的基本思路和方法,包括一些方法的使用示例和参数解释,具体的数据预处理案例case详见其他文章。如有错误之处还请指正! 目录 数据的质量评定 数据处理步骤 缺失值的处理 标记缺失值 删除 缺失值 填充 缺失值 重复值处理 异

    2024年02月04日
    浏览(58)
  • 文本预处理——文本数据分析

    2024年02月15日
    浏览(44)
  • SPSSPRO数据分析之——CSI指纹数据分析(预处理、降维等)

    目录 一、前言 二、数据准备 三、进行预处理  四、进行降维任务 五、正态性检测  六、描述性统计 七、频数分析 八、代码功能 SPSSPRO是一款全新的在线数据分析平台,可以用于科研数据的分析、数学建模等,对于那些不会编程或者刚进入科研的新人来说,这款工具再合适

    2024年02月13日
    浏览(58)
  • 人工智能:数据分析之数据预处理、分析模型与可视化

    在人工智能和数据科学领域,数据分析是一种核心过程,它帮助我们从大量的数据中提取有价值的信息。数据分析的质量和结果直接影响到决策的效率和准确性。在这篇博客中,我们将详细探讨数据分析的关键步骤,包括数据预处理、分析模型和可视化,并通过实际应用案例

    2024年03月10日
    浏览(76)
  • SPSSPRO数据分析之——CSI数据预处理、降维

    目录 一、前言 二、数据准备 三、进行预处理  四、进行降维任务 五、正态性检测  六、描述性统计 七、频数分析 八、代码功能 SPSSPRO是一款全新的在线数据分析平台,可以用于科研数据的分析、数学建模等,对于那些不会编程或者刚进入科研的新人来说,这款工具再合适

    2024年02月09日
    浏览(79)
  • 云计算与大数据分析:如何实现高效的数据清洗与预处理

    随着互联网的普及和数据的快速增长,数据分析和处理成为了企业和组织中的重要组成部分。大数据分析是指利用大量数据来发现新的信息和洞察,从而为企业和组织提供决策支持。云计算是一种基于互联网的计算资源共享和分配模式,它可以让企业和组织更加高效地利用计

    2024年04月11日
    浏览(48)
  • 基于Python的网络爬虫及数据处理---智联招聘人才招聘特征分析与挖掘的算法实现

    收藏和点赞,您的关注是我创作的动力   随着科学技术的发展,人类进入了互联网时代,不仅数据量庞大,而且数据种类繁多,Python简单易学, 语法清晰,在数据操作方面有着一定优势,成为了数据采集和可视化领域的热门语言。本论文主要是使用Python来作为开发语言,并

    2024年02月03日
    浏览(55)
  • GEO生信数据挖掘(六)实践案例——四分类结核病基因数据预处理分析

    前面五节,我们使用阿尔兹海默症数据做了一个数据预处理案例,包括如下内容: GEO生信数据挖掘(一)数据集下载和初步观察 GEO生信数据挖掘(二)下载基因芯片平台文件及注释 GEO生信数据挖掘(三)芯片探针ID与基因名映射处理 GEO生信数据挖掘(四)数据清洗(离群值

    2024年02月07日
    浏览(57)
  • GPT-4科研实践:数据可视化、统计分析、编程、机器学习数据挖掘、数据预处理、代码优化、科研方法论

    查看原文GPT4科研实践技术与AI绘图 GPT对于每个科研人员已经成为不可或缺的辅助工具,不同的研究领域和项目具有不同的需求。 例如在科研编程、绘图领域 : 1、编程建议和示例代码:  无论你使用的编程语言是Python、R、MATLAB还是其他语言,都可以为你提供相关的代码示例。

    2024年02月07日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包