机器学习实战机器学习特征工程最全解读

丰富的线上&线下活动,深入探索云世界

做任务,得社区积分和周边

最真实的开发者用云体验

让每位学生受益于普惠算力

让创作激发创新

资深技术专家手把手带教

遇见技术追梦人

技术交流,直击现场

海量开发者使用工具、手册,免费下载

极速、全面、稳定、安全的开源镜像

开发手册、白皮书、案例集等实战精华

为开发者定制的Chrome浏览器插件

如果我们对特征工程(featureengineering)做一个定义,那它指的是:利用领域知识和现有数据,创造出新的特征,用于机器学习算法;可以手动(manual)或自动(automated)。

在业界有一个很流行的说法:

这是因为,在数据建模上,「理想状态」和「真实场景」是有差别的,很多时候原始数据并不是规矩干净含义明确充分的形态:

而特征工程处理,相当于对数据做一个梳理,结合业务提取有意义的信息,以干净整齐地形态进行组织:

特征工程有着非常重要的意义:

我们这里用最简单和常用的Titanic数据集给大家讲解。

Titanic数据集可以通过seaborn工具库直接加载,如下代码所示:

importpandasaspdimportnumpyasnpimportseabornassnsdf_titanic=sns.load_dataset('titanic')其中数据集的数据字段描述如下图所示:

数据可以分为「结构化数据」和「非结构化数据」,比如在互联网领域,大部分存储在数据库内的表格态业务数据,都是结构化数据;而文本、语音、图像视频等就属于非结构化数据。

对于我们记录到的数据,我们通常又可以以「定量数据」和「定性数据」对齐进行区分,其中:

如下图是两类数据示例以及它们常见的处理分析方法的总结:

实际数据挖掘或者建模之前,我们会有「数据预处理」环节,对原始态的数据进行数据清洗等操作处理。因为现实世界中数据大体上都是不完整、不一致的「脏数据」,无法直接进行数据挖掘,或者挖掘结果差强人意。

「脏数据」产生的主要成因包括:

数据清洗过程包括数据对齐、缺失值处理、异常值处理、数据转化等数据处理方法,如下图所示:

下面我们注意对上述提到的处理方法做一个讲解。

数据缺失是真实数据中常见的问题,因为种种原因我们采集到的数据并不一定是完整的,我们有一些缺失值的常见处理方式:

具体的处理方式可以展开成下图:

下面回到我们的Titanic数据集,我们演示一下各种方法:

我们先对数据集的缺失值情况做一个了解(汇总分布):

df_titanic.isnull().sum()survived0pclass0sex0age177sibsp0parch0fare0embarked2class0who0adult_male0deck688embark_town2alive0alone0(1)删除最直接粗暴的处理是剔除缺失值,即将存在遗漏信息属性值的对象(字段,样本/记录)删除,从而得到一个完备的信息表。优缺点如下:

在我们当前Titanic的案例中,embark_town字段有2个空值,考虑删除缺失处理下。

第2大类是我们可以通过一些方法去填充缺失值。比如基于统计方法、模型方法、结合业务的方法等进行填充。

根据业务知识来进行人工手动填充。

将空值作为一种特殊的属性值来处理,它不同于其他的任何属性值。如所有的空值都用unknown填充。一般作为临时填充或中间过程。

代码实现

df_titanic['embark_town'].fillna('unknown',inplace=True)③统计量填充若缺失率较低,可以根据数据分布的情况进行填充。常用填充统计量如下:

中位数填充——fare:缺失值较多,使用中位数填充

df_titanic['fare'].fillna(df_titanic['fare'].median(),inplace=True)众数填充——embarked:只有两个缺失值,使用众数填充

df_titanic['embarked'].isnull().sum()#执行结果:2df_titanic['embarked'].fillna(df_titanic['embarked'].mode(),inplace=True)df_titanic['embarked'].value_counts()#执行结果:#S64同类均值填充

age:根据sex、pclass和who分组,如果落在相同的组别里,就用这个组别的均值或中位数填充。

如果其他无缺失字段丰富,我们也可以借助于模型进行建模预测填充,将待填充字段作为Label,没有缺失的数据作为训练数据,建立分类/回归模型,对待填充的缺失字段进行预测并进行填充。

最近距离邻法(KNN)

回归(Regression)

我们以Titanic案例中的age字段为例,讲解一下:

还可以用插值法对数据填充,细分一下包括线性插值、多重插补、热平台插补、拉格朗日插值、牛顿插值等。

线性插值法

使用插值法可以计算缺失值的估计值,所谓的插值法就是通过两点(x0,y0),(x1,y1)估计中间点的值。假设y=f(x)是一条直线,通过已知的两点来计算函数f(x),然后只要知道x就能求出y,以此方法来估计缺失值。

.interpolate(method='linear',axis)方法将通过linear插值使用沿着给定axis的值替换NaN值,这个差值也就是前后或者上下的中间值

df_titanic['fare'].interpolate(method='linear',axis=0)同时,也可用行值插入

df_titanic['fare'].interpolate(method='linear',axis=1)多重插补(MultipleImputation)

多重插补方法分为三个步骤:

有另外一种非常有意思的填充方式,叫做「哑变量填充」,在变量为离散型,且不同值较少的情况下可以采用,以Titanic数据为例:

以下为参考代码示例:

sex_list=['MALE','FEMALE',np.NaN,'FEMALE','FEMALE',np.NaN,'MALE']df=pd.DataFrame({'SEX':sex_list})display(df)df.fillna('NA',inplace=True)df=pd.get_dummies(df['SEX'],prefix='IS_SEX')display(df)#原始数据SEX0MALE1FEMALE2NaN3FEMALE4FEMALE5NaN6MALE#填充后IS_SEX_FEMALEIS_SEX_MALEIS_SEX_NA001011002001310041005001601当特征值缺失超过80%以上,建议删除【或加入「是」「否」标记位信息】,容易影响模型效果

df_titanic.drop(["deck"],axis=1)2.3异常值处理数据质量也会很大程度影响机器学习应用效果,数据的错误值或异常值可能会造成测量误差或异常系统条件的结果,给模型学习带来很大的问题。实际我们很多时候会有异常值检测与处理环节,下面给大家做一个梳理。

通常用户用某个统计分布对数据点进行建模,再以假定的模型,根据点的分布来确定是否异常。

如通过分析统计数据的散度情况,即数据变异指标,对数据的分布情况有所了解,进而通过数据变异指标来发现数据中的异常点数据。

常用的数据变异指标有极差、四分位数间距、均差、标准差、变异系数等等,如变异指标的值大表示变异大、散布广;值小表示离差小,较密集。

如果数据近似正态分布,在3σ原则下,异常值为一组测定值中与平均值的偏差超过3倍标准差的值。

箱型图判断异常值的方法以四分位数和四分位距为基础,四分位数具有鲁棒性:25%的数据可以变得任意远并且不会干扰四分位数,所以异常值不能对这个标准施加影响。因此箱型图识别异常值比较客观,在识别异常值时有一定的优越性。

我们也可以基于模型对异常值检测,基本思路是先建立一个数据模型,那些同模型不能完美拟合的对象就视作异常。

优点:有坚实的统计学理论基础,当存在充分的数据和所用的检验类型的知识时,这些检验可能非常有效。

缺点:对于多元数据,可用的选择少一些,并且对于高维数据,这些检测可能性很差。

我们还有基于距离的方法可以用于异常检测。这类方法基于下面这个假设:如果一个数据对象和大多数点距离都很远,那这个对象就是异常。通过定义对象之间的临近性度量,根据距离判断异常对象是否远离其他对象,主要使用的距离度量方法有绝对距离(曼哈顿距离)、欧氏距离和马氏距离等方法。

一个很直接的异常检测思路是基于分布密度来做,具体为:考察当前点周围密度,局部异常点/离群点的局部密度显著低于大部分近邻点。这类方法适用于非均匀的数据集。

我们可以基于聚类的方法进行异常检测,远离cluster的样本更可能是异常值。

不过该方法会受到聚类cluster个数k的影响,一种策略是对于不同的簇个数重复该分析;另一种方法是找出大量小簇,其想法是:

同样的,我们也有基于近邻度的思路来做异常检测,我们认为异常点远离大部分的点。这种方法比统计学方法更一般、更容易使用,因为确定数据集的有意义的邻近性度量比确定它的统计分布更容易。一个对象的异常点得分由到它的K-最近邻的距离给定,所以异常点得分对K的取值高度敏感:

为了使该方案对于K的选取更具有鲁棒性,可以使用K个最近邻的平均距离。

在数据处理阶段将离群点作为影响数据质量的异常点考虑,而不是作为通常所说的异常检测目标点,一般采用较为简单直观的方法,结合箱线图和MAD的统计方法判断变量的离群点。如下为绘制散点图根据分布直接判断。

对异常值处理,需要具体情况具体分析,异常值处理方法常用的有以下几种:

前序的数据预处理过程能保证我们拿到干净整齐准确的数据,但这些数据未必对于建模是最有效的,下一步我们通常会进行特征构建,结合业务场景产生衍生变量来提升数据表达能力和模型建模效果。

统计特征是一类非常有效的特征,尤其在时序问题场景中,以下为统计特征构建的一些思考维度和方法:

回到Titanic数据集,我们来看看结合业务理解,我们可以做哪些新特征:

年龄处理

我们对年龄age字段进行进一步处理,考虑到不同的年龄段对应的人群可能获救概率不同,我们根据年龄值分成不同区间段,对应到child、young、midlife、old等

defage_bin(x):ifx<=18:return'child'elifx<=30:return'young'elifx<=55:return'midlife'else:return'old'df_titanic['age_bin']=df_titanic['age'].map(age_bin)df_titanic['age_bin'].unique()执行结果:array(['young','midlife','child','old'],dtype=object)抽取「称呼」特征

我们在name字段里,可以看到各种不同的称呼,如「Mr」「Master」「Dr」等,这些称呼体现了乘客的身份等信息,我们可以对其做抽取构建新的特征。

#提取称呼df_titanic['title']=df_titanic['name'].map(lambdax:x.split(',')[1].split('.')[0].strip())df_titanic['title'].value_counts()执行结果如下:

Mr757Miss260Mrs197Master61Rev8Dr8Col4Ms2Major2Mlle2Dona1Sir1Capt1Don1Lady1Mme1theCountess1Jonkheer1我们做一个简单的「称呼」统计

#对称呼细分,是官员,还是皇室,还是女士、先生、小姐df_titanic['title'].unique()执行结果:

array(['Mr','Mrs','Miss','Master','Don','Rev','Dr','Mme','Ms','Major','Lady','Sir','Mlle','Col','Capt','theCountess','Jonkheer','Dona'],dtype=object)下面我们对这些「称呼」「称谓」做一个规范化统一。

title_dictionary={"Mr":"Mr","Mrs":"Mrs","Miss":"Miss","Master":"Master","Don":"Royalty","Rev":"Officer","Dr":"Officer","Mme":"Mrs","Ms":"Mrs","Major":"Officer","Lady":"Royalty","Sir":"Royalty","Mlle":"Miss","Col":"Officer","Capt":"Officer","theCountess":"Royalty","Jonkheer":"Royalty","Dona":'Mrs'}df_titanic['title']=df_titanic['title'].map(title_dictionary)df_titanic['title'].value_counts()执行结果如下:

Mr757Miss262Mrs201Master61Officer23Royalty5抽取家庭规模

在Titanic上,有的成员之间有亲属关系,考虑到家族大小对于最终是否获救也有影响,我们可以构建一个family_size的特征,用于表征家庭规模。

df_titanic['family_size']=df_titanic['sibsp']+df_titanic['parch']+1df_titanic['family_size'].head()执行结果如下:

02122132413.2周期值在电商等场景下,数据有一定的周期规律,我们可以提取一些周期值作为有效信息。

时序周期的一些考虑维度如下:

数据分桶,是对连续值属性处理的一种常用方法,它指的是我们把连续数值切段,并把连续值归属到对应的段中。数据分桶也叫做数据分箱或离散化。

指根据业务经验或者常识等自行设定划分的区间,然后将原始数据归类到各个区间中。

按照相同宽度将数据分成几等份。

从最小值到最大值之间,均分为N等份。如果A、B为最小最大值,则每个区间的长度为W=(BA)/N,区间边界值为A+W、A+2W、…、A+(N1)W。

等距分箱只考虑边界,每个等份里面的实例数量可能不等。等距分桶的缺点是受到异常值的影响比较大。

将数据分成几等份,每等份数据里面的个数是一样的。

在等频分箱中,区间的边界值要经过计算获得,最终每个区间包含大致相等的实例数量。比如说N=5,每个区间应该包含大约20%的实例。

我们先对船票价格做一个等频切分(大家如果对船票价格进行分布绘图,会发现是很长尾的分布,并不适合等距切分),看看分开的区间段。

#qcut等频率分箱df_titanic['fare_bin'],bins=pd.qcut(df_titanic['fare'],5,retbins=True)df_titanic['fare_bin'].value_counts()结果如下:

(7.854,10.5]184(21.679,39.688]180(-0.001,7.854]179(39.688,512.329]176(10.5,21.679]172bins#array([0.,7.8542,10.5,21.6792,39.6875,512.3292])下面根据区间段对其进行等频切分

#对船票fare进行分段分桶deffare_cut(fare):iffare<=7.8958:return0iffare<=10.5:return1iffare<=21.6792:return2iffare<=39.6875:return3return4df_titanic['fare_bin']=df_titanic['fare'].map(fare_cut)相比船票价格,年龄age字段的分布更加集中,且区间大小比较明确,我们采用等距切分,代码如下:

#cut等距离分箱bins=[0,12,18,65,100]pd.cut(df_titanic['age'],bins).value_counts(2)Best-KS分桶(3)卡方分桶自底向上的(即基于合并的)数据离散化方法,依赖于卡方检验:具有最小卡方值的相邻区间合并在一起,直到满足确定的停止准则。

基本思想:

如果两个相邻的区间具有非常类似的类分布,则这两个区间可以合并;否则,它们应当保持分开。而低卡方值表明它们具有相似的类分布。

实现步骤:

还有最小熵分箱法,需要使总熵值达到最小,也就是使分箱能够最大限度地区分因变量的各类别。

熵是信息论中数据无序程度的度量标准,提出信息熵的基本目的是找出某种符号系统的信息量和冗余度之间的关系,以便能用最小的成本和消耗来实现最高效率的数据存储、管理和传递。

数据集的熵越低,说明数据之间的差异越小,最小熵划分就是为了使每箱中的数据具有最好的相似性。给定箱的个数,如果考虑所有可能的分箱情况,最小熵方法得到的箱应该是具有最小熵的分箱。

我们在有些场景下会考虑特征组合构建强特征,如下为常用的特征组合构建方式:

1)离散+离散:构建笛卡尔积(即两两组合「且」关系)。2)离散+连续:连续特征分桶后进行笛卡尔积或基于类别特征groupby构建统计特征。3)连续+连续:加减乘除,多项式特征,二阶差分等。

针对连续值特征,我们对几个特征构建多项式特征,以达到特征组合与高阶增强的作用。

在Titanic的例子中,如下为数值型特征:

df_titanic_numerical=df_titanic[['age','sibsp','parch','fare','family_size']]df_titanic_numerical.head()我们可以参考下述代码构建多项式特征

我们对于构建完的特征,会做一些「特征变换」的操作,以适应不同的模型,更好地完成建模。

标准化操作也称作Z-score变换,它使数值特征列的算数平均为0,方差(以及标准差)为1,如下图所示。

标准化操作的参考代码如下:

fromsklearn.preprocessingimportStandardScale#标准化模型训练Stan_scaler=StandardScaler()Stan_scaler.fit(x)x_zscore=Stan_scaler.transform(x)x_test_zscore=Stan_scaler.transform(x_test)joblib.dump(Stan_scaler,'zscore.m')#写入文件4.2归一化(Normalization)归一化操作会基于向量模长调整数据幅度大小,但并不会改变原始数据的顺序。如下图所示:

幅度缩放是为了让不同特征的取值在大体一致的数量级和数据区间内,比较常用的方法是最大最小值缩放,如下图所示:

下面为幅度缩放操作的参考代码:

fromsklearnimportpreprocessingmin_max_scaler=preprocessing.MinMaxScaler()min_max_scaler.fit_transform(x)x_minmax=min_max_scaler.transform(x)x_test_minmax=min_max_scaler.transform(x_test)joblib.dump(min_max_scaler,'min_max_scaler.m')#写入文件4.4归一化VS标准化归一化和标准化是两个非常常见的特征变换操作,下面我们来对比一下标准化和归一化:

它们分别的适用场景可以归纳总结如下:

我们在有些场景下,还会对数值字段进行分布调整或者校正,利用统计或数学变换来减轻数据分布倾斜的影响。使原本密集的区间的值尽可能的分散,原本分散的区间的值尽量的聚合。

大部分变换函数都属于幂变换函数簇,主要作用是稳定方差,保持分布接近于正态分布并使得数据与分布的平均值无关。

我们来看看一些典型的非线性统计变换。

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

log变换属于幂变换函数簇,数学表达式为

$$y=log_{b}(x)$$

下面我们对Titanic数据集中的船票价格字段进行log1p变换,示例代码如下:

box-cox变换的主要特点是引入一个参数,通过数据本身估计该参数进而确定应采取的数据变换形式,box-cox变换可以明显地改善数据的正态性、对称性和方差相等性,对许多实际数据都是行之有效的。

box-cox变换函数数学表达式如下:

$$y(\lambda)=\left\{\begin{array}{ll}\frac{y^{\lambda}-1}{\lambda},&\lambda\neq0\\\lny,&\lambda=0\end{array}\right.$$

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

下面我们对Titanic数据集中的船票价格字段进行box-cox变换,示例代码如下:

对于类别型的字段特征(比如颜色、类型、好坏程度),有很多模型并不能直接处理,我们对其进行编码后能更好地呈现信息和支撑模型学习。有以下常见的类别型变量编码方式:

标签编码(labelencoding)是最常见的类别型数据编码方式之一,编码值介于0和n_classes-1之间的标签。

例如:比如有[dog,cat,dog,mouse,rabbit],我们把其转换为[0,1,0,2,3]。

标签编码的参考代码如下:

fromsklearn.preprocessingimportLabelEncoderle=LabelEncoder()le.fit(["超一线","一线","二线","三线"])print('特征:{}'.format(list(le.classes_)))#输出特征:['一线','三线','二线','超一线']print('转换标签值:{}'.format(le.transform(["超一线","一线","二线"])))#输出转换标签值:array([302]...)print('特征标签值反转:{}'.format(list(le.inverse_transform([2,2,1]))))#输出特征标签值反转:['二线','二线','三线(2)独热向量编码(onehotencoding)独热编码通常用于处理类别间不具有大小关系的特征。

例如:特征:血型,一共有四种类别(A,B,AB,O),采用独热编码后,会把血型变成有一个4维的稀疏向量

最终生成的稀疏向量的维度,和类别数相同。

sex_list=['MALE','FEMALE',np.NaN,'FEMALE','FEMALE',np.NaN,'MALE']df=pd.DataFrame({'SEX':sex_list})display(df)df.fillna('NA',inplace=True)df=pd.get_dummies(df['SEX'],prefix='IS_SEX')display(df)最终变换前后的结果如下:

#原始数据SEX0MALE1FEMALE2NaN3FEMALE4FEMALE5NaN6MALE#独热向量编码后IS_SEX_FEMALEIS_SEX_MALEIS_SEX_NA001011002001310041005001下面我们对'sex','class','pclass','embarked','who','family_size','age_bin'这些字段都进行独热向量编码。

importnumpyasnpfromsklearn.preprocessingimportOneHotEncoder#非负整数表示的标签列表labels=[0,1,0,2]#行向量转列向量labels=np.array(labels).reshape(len(labels),-1)#独热向量编码enc=OneHotEncoder()enc.fit(labels)targets=enc.transform(labels).toarray()#如果不加toarray()的话,输出的是稀疏的存储格式,即索引加值的形式,也可以通过参数指定sparse=False来达到同样的效果输出结果如下:

array([[1.,0.,0.],[0.,1.,0.],[1.,0.,0.],[0.,0.,1.]])(3)标签二值化(LabelBinarizer)功能与OneHotEncoder一样,但是OneHotEncoder只能对数值型变量二值化,无法直接对字符串型的类别变量编码,而LabelBinarizer可以直接对字符型变量二值化。

示例代码如下:

fromsklearn.preprocessingimportLabelBinarizerlb=LabelBinarizer()labelList=['yes','no','no','yes','no2']#将标签矩阵二值化dummY=lb.fit_transform(labelList)print("dummY:",dummY)#逆过程yesORno=lb.inverse_transform(dummY)print("yesOrno:",yesORno)输出如下:

通过特征降维希望达到的目的:

常用的降维方法有:

这里降维的讲解,我们给大家基于iris数据集讲解:

PCA降维的参考代码实现如下:

SVD方法的主要步骤如下:

$$A^{T}A=\left(U\SigmaV^{T}\right)^{T}U\SigmaV^{T}=V\Sigma^{T}U^{T}U\SigmaV^{T}=V\Sigma^{T}\SigmaV^{T}=V\Sigma^{2}V^{T}$$

所以$V$是$A^{T}A$特征值分解的特征向量按列组成的正交矩阵,$\Sigma^{2}$是$A^{T}A$特征值组成的对角矩阵,也可以看出$A_{m\timesn}$的奇异值$\sigma_{i}$是$A^{T}A$特征值$$\lambda_{i}$$的平方根。

$$\sigma_{i}=\sqrt{\lambda_{i}}$$

假如$A^{T}A$的特征向量为$v_{i}$,$U$中对应的$u_{i}$则可以由下式求出:

$$u_{i}=\frac{Av_{i}}{\sigma_{i}}$$

也即奇异值分解的关键在于对$A^{T}A$进行特征值分解。

对应的代码参考实现如下:

PCA求解关键在于求解协方差矩阵$C=\frac{1}{m}XX^{T}$的特征值分解。

SVD关键在于$A^{T}A$的特征值分解。

很明显二者所解决的问题非常相似,都是对一个实对称矩阵进行特征值分解,如果取:

$$A=\frac{X^{T}}{\sqrt{m}}$$

则有:

$$A^{T}A=\left(\frac{X^{T}}{\sqrt{m}}\right)^{T}\frac{X^{T}}{\sqrt{m}}=\frac{1}{m}XX^{T}$$

此时SVD与PCA等价,所以PCA问题可以转化为SVD问题求解。

是有监督的降维,通过最小化类内离散度与最大化类间离散度来获得最优特征子集。

对应的降维参考实现代码如下:

PCA试图寻找到方差最大的正交的主成分分量轴LDA发现可以最优化分类的特征子空间LDA和PCA都是可用于降低数据集维度的线性转换技巧PCA是无监督算法LDA是监督算法LDA是一种更优越的用于分类的特征提取技术

T-SNE(t-distributedstochasticneighborembedding)是一种非线性降维方法,参考的代码实现如下:

特征选择是在建模过程中经常会用到的一个处理,也有重要意义:

总体来说,进行特征选择有2个主要考虑方向:

对特征选择的方法进行归类,又大体可以归纳为下述3种:

这是通过特征本身的方差来筛选特征的类。

比如一个特征本身的方差很小,就表示样本在这个特征上基本没有差异,可能特征中的大多数值都一样,甚至整个特征的取值都相同,那这个特征对于样本区分没有什么作用。

我们会剔除掉方差非常小的字段特征,参考代码实现如下:

如下为卡方过滤的参考代码示例:

其特征选择的参考代码如下:

fromsklearn.feature_selectionimportf_classiff_value,p_value=f_classif(X,y)#根据p值,得出k值k=f_value.shape[0]-(p_value>0.05).sum()#筛选后特征X_classif=SelectKBest(f_classif,k=14).fit_transform(X,y)(4)互信息法互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。

fromsklearn.feature_selectionimportmutual_info_classifasMIC#互信息法mic_result=MIC(X,y)#互信息量估计k=mic_result.shape[0]-sum(mic_result<=0)#16X_mic=SelectKBest(MIC,k=16).fit_transform(X,y)5.2包裹式Wrapper(1)递归特征删除法递归消除删除法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。使用feature_selection库的RFE类来选择特征的代码如下:

fromsklearn.feature_selectionimportRFEfromsklearn.linear_modelimportLogisticRegression#递归特征消除法,返回特征选择后的数据#参数estimator为基模型#参数n_features_to_select为选择的特征个数X_ref=RFE(estimator=LogisticRegression(),n_features_to_select=10).fit_transform(X,y)(2)特征重要性评估我们基于一些模型(如各类树模型)可以得到特征重要度,进而进行筛选

fromsklearn.ensembleimportExtraTreesClassifier#建模与获取特征重要度model=ExtraTreesClassifier()model.fit(X,y)print(model.feature_importances_)#特征重要度排序feature=list(zip(X.columns,model.feature_importances_))feature=pd.DataFrame(feature,columns=['feature','importances'])feature.sort_values(by='importances',ascending=False).head(20)(3)排列重要性评估我们还有一类方法可以评估特征重要度,进而进行筛选,叫作排列重要度。

原理:在训练机器学习模型之后计算置换重要性。这种方法在向模型提出假设,如果在保留目标和所有其他列的同时随机打乱一列验证集特征数据,对预测机器学习模型的准确性的影响程度。对于一个具有高度重要性的特征,random-reshuffle会对机器学习模型预测的准确性造成更大的损害。

优点:快速计算;易于使用和理解;特征重要性度量的属性;追求特征稳定性。

参考代码实现如下:

使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。

使用feature_selection库的SelectFromModel类结合带L1惩罚项的逻辑回归模型,来选择特征的代码如下:

fromsklearn.feature_selectionimportSelectFromModelfromsklearn.linear_modelimportLogisticRegression#带L1和L2惩罚项的逻辑回归作为基模型的特征选择,这个设置带L1惩罚项的逻辑回归作为基模型的特征选择lr=LogisticRegression(solver='liblinear',penalty="l1",C=0.1)X_sfm=SelectFromModel(lr).fit_transform(X,y)X_sfm.shape(891,7使用feature_selection库的SelectFromModel类结合SVM模型,来选择特征的代码如下:

fromsklearn.feature_selectionimportSelectFromModelfromsklearn.svmimportLinearSVClsvc=LinearSVC(C=0.01,penalty='l1',dual=False).fit(X,y)model=SelectFromModel(lsvc,prefit=True)X_sfm_svm=model.transform(X)X_sfm_svm.shape(891,7(2)基于树模型树模型中GBDT也可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型,来选择特征的代码如下:

fromsklearn.feature_selectionimportSelectFromModelfromsklearn.ensembleimportGradientBoostingClassifier#GBDT作为基模型的特征选择gbdt=GradientBoostingClassifier()X_sfm_gbdt=SelectFromModel(gbdt).fit_transform(X,y)5.4特征选择总结关于特征选择,做一个经验总结,如下:

我们可能会做的一些数据预处理与特征处理如下:

结合业务场景和数据分布,进行合理的缺失值、异常值处理。

建议不要上来就做PCA或LDA降维,最好先构建特征并对特征做筛选。

median(N1)_by(C1)中位数mean(N1)_by(C1)算术平均数mode(N1)_by(C1)众数min(N1)_by(C1)最小值max(N1)_by(C1)最大值std(N1)_by(C1)标准差var(N1)_by(C1)方差freq(C2)_by(C1)频数N1-median(N1)_by(C1)N1-mean(N1)_by(C1)在Scikit-Learn和XGBoost里,可以基于apply()以及decision_path()等方法实现。

THE END
1.数据清洗的具体方法有哪些?数据清洗流程数据清洗的具体方法有哪些? 清洗数据是数据分析和机器学习项目中至关重要的一步,其目标在于识别并纠正数据集中的错误、遗漏或不一致,以提高数据质量和后续分析结果的准确性。以下是一个详细的数据清洗流程,通常包括以下几个步骤: 1.数据收集与理解 收集数据:从各种来源(如数据库、API、文件等)获取数据。https://blog.csdn.net/Shaidou_Data/article/details/143205411
2.通透!十大数据清洗方法!!51CTO博客文本数据清洗 数据类型转换 特征工程 咱们一起来探讨~ 1. 缺失值处理 原理 缺失值处理是指在数据集中存在空值或缺失数据的情况下,通过合适的策略填补或处理这些缺失值,以减少对后续分析和模型训练的影响。常见的缺失值处理方法包括删除缺失值、均值填补、中位数填补、众数填补和插值法。 https://blog.51cto.com/u_15671528/12187385
3.数据清洗的方法有哪些?一般来说,数据中是存在噪音的,那么噪音是怎么清洗的呢?我们就在这篇文章中给大家介绍一下数据清洗的方法。通常来说,清洗数据有三个方法,分别是分箱法、聚类法、回归法。这三种方法各有各的优势,能够对噪音全方位的清理。分箱法是一个经常使用到方法,所谓的分箱法,就是将需要处理的数据根据一定的规则放进http://baijiahao.baidu.com/s?id=1711739383699713605&wfr=spider&for=pc
4.数据清洗的方法包括什么常见问题数据清洗的方法包括什么 数据清洗的方法包括:1、分箱法,就是将需要处理的数据根据一定的规则放进箱子里,然后进行测试;2、回归法,就是利用函数的数据进行绘制图像,然后对图像进行光滑处理;3、聚类法,就是将抽象的对象进行集合分组,成为不同的集合,找到在集合意外的孤点。https://m.php.cn/faq/478619.html
5.值得收藏!数据清洗的十类常用方法数据清洗是数据治理过程中的一个重要环节,它指的是对原始数据进行筛选、修复、转换和处理,以确保数据的准确性、完整性和一致性。 在数据清洗过程中,不仅需要明确数据清洗的对象,还需要根据具体的情况选择合适的数据清理方法。以下是不同对象所对应不同的数据清洗方法。 https://www.fanruan.com/bw/doc/178453
6.数据分析中的数据预处理包括哪些步骤一、数据清洗 数据清洗是数据预处理的第一步,主要是为了处理原始数据中存在的错误、缺失、重复、异常等问题。具体步骤如下: 1.去重:检查数据集中是否存在重复的数据记录,如有重复,删除其中的一条或多条记录。 2.处理缺失值:数据集中可能存在某些数据缺失的情况,可以通过删除缺失值、替换缺失值或使用插值方法进行处https://www.linkflowtech.com/news/1073
7.数据处理方法有哪些?数据处理的三种方法各位老铁们好,相信很多人对数据处理方法有哪些都不是特别的了解,因此呢,今天就来为大家分享下关于数据处理方法有哪些以及数据处理的三种方法的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧! 一、数据处理的常用方法有 1、列表法:是将实验所获得的数据用表格的形式进行排列的数据处理方法。列表法的https://www.duote.com/tech/202401/534651.html
8.数据清洗的常见问题有哪些?数据清洗的常见问题有哪些? 收藏 数据清洗是数据处理流程中不可或缺的一步,其目的是对原始数据进行筛选、转换和修正,以确保数据质量符合使用要求。然而,在进行数据清洗时,常会遇到一些问题,下面将介绍一些常见的数据清洗问题及解决方法。 缺失数据 在实际数据处理过程中,经常会遇到部分数据缺失的情况,这可能是由于人为https://www.cda.cn/bigdata/202776.html
9.科学网—[转载]制造业生产过程中多源异构数据处理方法综述摘要:随着现代制造业向着自动化、信息化、智能化方向快速发展,生产过程中会产生大量的多源异构数据。对多源异构数据的有效处理和深度挖掘可为生产制造者提供更有效的生产调度、设备管理等策略,从而提高生产质量和效率。针对制造业生产过程中多源异构数据的处理方法与技术等进行系统性的综述,首先明确了制造业生产过程多源异构https://blog.sciencenet.cn/blog-3472670-1287069.html
10.数据清理技术的主要目的包括()数据处理的意义有数据处理是实现数据共享的关键步骤、是检验数据质量的关键环节() A. 是实现空间数据有序化的关键环节 B. 是合理安排工作的环节 C. 是实现数据一致化的准则 D. 是完成数据的步骤 查看完整题目与答案 电子商务中下列不属于数据清洗的是() A. 一致性检查 B. 无效值处理 C. 成对删https://www.shuashuati.com/ti/5c1a68404f6a4076adcda2411f7654b7.html
11.解密代码模型StarCoder&CodeLlamaStarcoder团队对不同类型的编程语言有个性化的处理逻辑,下文我们进一步分析了具体的处理方法。 人工检查 为了筛选出高质量的数据,StarCoder团队通过人工检查的方式进行数据处理。首先从 The Stack 数据集中为每种编程语言随机选择 30,000 个文件,按扩展名对它们进行分类,并为每个扩展名保留最多 1,000 个文件。Starhttps://hub.baai.ac.cn/view/34967