数据挖掘小白系列!数据预处理及特征工程(上)!

17 篇文章 0 订阅
13 篇文章 2 订阅

本文章只用于学习交流不用于任何商业行为,所有知识点资料来源于网络,如有任何不当之处请私信联系,作者会及时改正

本文中总结自文档所有标注的页码都是附件参考文档中的页码

由于markdown不支持附件下载,附件链接如下

http://note.youdao.com/noteshare?id=05a144c93bd1f66d0a25881a5fe5ce65

1数据挖掘流程

=============================
ALT
在这里插入图片描述
1. 获取数据

2. 数据预处理
数据预处理的目的:数据中检测,纠正不适用于模型的数据,让数据适应模型,匹配模型的需求

可能面对的问题有:数据类型不同,有噪声,有异常,有缺失,数据出错,量纲不一,有重复,数据是偏态,数据量太大或太小

3. 特征工程:
特征工程是将原始数据转换为更能代表预测模型的潜在问题的特征的过程,可以通过特征选取,特征提取,特征创造等手段。其中创造特征又经常以降维算法的方式实现。
在这里插入图片描述

特征工程的目的:1) 降低计算成本,2) 提升模型上限

可能面对的问题有:特征之间有相关性,特征和标签无关,特征太多或太小,或者干脆就无法表现出应有的数据现象或无法展示数据的真实面貌

4. 建模,测试模型并预测出结果

5. 上线,验证模型效果

推荐参考:https://blog.csdn.net/AvenueCyy/article/details/104459466

sklearn相关常用模块

=============================

模块preprocessing:几乎包含数据预处理的所有内容
模块Impute:填补缺失值专用
模块feature_selection:包含特征选择的各种方法的实践
模块decomposition:包含降维算法
推荐参考:https://www.cnblogs.com/jasonfreak/p/5448462.html

2数据预处理

=============================

2.1无纲量化

概念:

不同规格/分布的数据转换到统一规格/特定分布

目的:

         如梯度和矩阵为核心的算法(逻辑回归/SVM/神经网络)中可以加快求解速度
         如距离类模型(如K近邻,K-Means聚类)可以避免异常值从而提升模型效果

分类:

         中心化处理(Zero-centered或者Mean-subtraction):让所有记录减去一个固定值,即让数据样本数据平移到某个位置。
          缩放处理(Scale):通过除以一个固定值,将数据固定在某个范围之中,取对数也算是一种缩放处理。

2.2skelarn中预处理函数

2.2.1preprocessing.MinMaxScaler数据归一化(Normalization/Min-Max Scaling)

数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间的过程

注意:Normalization是归一化,不是正则化,真正的正则化是regularization,不是数据预处理的一种手段。归一化之后的数据服从正态分布

重要参数,feature_range

         控制我们希望把数据压缩到的范围,默认是[0,1]。

2.2.2preprocessing.StandardScaler数据标准化(Standardization)

当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布)的过程,

2.2.3StandardScaler和MinMaxScaler选哪个?

StandardScaler:对异常值不敏感的算法(PCA,聚类,逻辑回归,支持向量机,神经网络)

MinMaxScaler:不涉及距离度量、梯度、协方差计算或数据需要被压缩到特定区间时使用广泛,比如数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于[0,1]区间之中。

MaxAbsScaler:希望压缩数据,却不影响数据的稀疏性时(不影响矩阵中取值为0的个数时)

RobustScaler:在异常值多,噪声非常大时,我们可能会选用分位数来无量纲化

建议:先试试看StandardScaler进行特征缩放,效果不好就具体看情况,详见下表
在这里插入图片描述

2.2.4impute.SimpleImputer缺失值处理

在这里插入图片描述

2.2.5编码标签 preprocessing.LabelEncoder:分类标签专用,将分类转换为分类数值

from sklearn.preprocessing import LabelEncodery = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维

le = LabelEncoder() #实例化
le = le.fit(y) #导入数据
label = le.transform(y)   #transform接口调取结果
.classes_ #属性.classes_查看标签中究竟有多少类别
label #查看获取的结果
labelle.fit_transform(y) #也可以直接fit_transform一步到位
le.inverse_transform(label) #使用inverse_transform可以逆转

'''简易写法:'''
from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])

2.2.6编码分类特征

=============================
大多数算法,譬如逻辑回归,支持向量机SVM,k近邻算法等都只能够处理数值型数据,除专用算法外都不能处理文字

preprocessing.OrdinalEncoder:分类特征专用,将分类特征转换为分类数值
from sklearn.preprocessing import OrdinalEncoder

data_.head()
data_ = data.copy()
OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_
#接口categories_对应LabelEncoder的接口classes_,一模一样的功能
data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
data_.head()

'''简易写法:'''
from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1] = OrdinalEncoder().fit_transform(data.iloc[:,-1])
preprocessing.OneHotEncoder:独热编码,创建哑变量

OrdinalEncoder可以用来处理有序变量,但对于名义变量,我们只有使用哑变量的方式来处理

1) 舱门(S,C,Q)三种取值S,C,Q是相互独立的,彼此之间完全没有联系,表达的是S≠C≠Q的概念。这是名义变量
2) 学历(小学,初中,高中)三种取值不是完全独立的,我们可以明显看出,在性质上可以有高中>初中>小学这样的有联系,但取值之间却不是可以计算,我们不能说小学 + 某个取值 = 初中。这是有序变量

重要属性get_feature_names()#返回特征名字,在特征多记不清的时候使用
data.head()
from sklearn.preprocessing import OneHotEncoder
X = data.iloc[:,1:-1]
result
#依然可以直接一步到位,但为了给大家展示模型属性,所以还是写成了三步
OneHotEncoder(categories='auto').fit_transform(X).toarray()
#依然可以还原
pd.DataFrame(enc.inverse_transform(result))
enc.get_feature_names()'''返回特征名字,在特征多记不清的时候使用'''
result
result.shape
#axis=1,表示跨行进行合并(也就是将两表左右相连),如果是axis=0,就是将两表上下相连
newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
newdata.head()
newdata.drop(["Sex","Embarked"],axis=1,inplace=True)
newdata.columns = 
["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
newdata.head()

在这里插入图片描述

常见数据类型及统计量

在这里插入图片描述

2.2.7编码连续特征

=============================

sklearn.preprocessing.Binarizer二值化

根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。默认阈值为0时,特征中所有的正值都映射到1。
二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。

#将年龄二值化
data_2 = data.copy()
from sklearn.preprocessing import Binarizer
X = data_2.iloc[:,0].values.reshape(-1,1) #类为特征专用,所以不能使用一维数组
transformer = Binarizer(threshold=30).fit_transform(X)
transformer
preprocessing.KBinsDiscretizer分段

这是将连续型变量划分为分类变量的类,能够将连续型变量排序后按顺序分箱后编码。总共包含三个重要参数:
在这里插入图片描述

'''
strategy说明:
值为0~100,其中0~10有20个样本,11~20有50个样本,21~100有50个样本
uniform:分成5个箱就是0~20,21~40,以此类推,按照值(值域)不管样本是否均匀
quantile:分成5个箱,0~10分成一个,21~40的前20个分成一个,以此类推,按照样本数量来分
kmeans:自己聚类来分箱
'''
from sklearn.preprocessing import KBinsDiscretizer
X = data.iloc[:,0].values.reshape(-1,1) 
est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
est.fit_transform(X)
#查看转换后分的箱:变成了一列中的三箱
set(est.fit_transform(X).ravel())
est = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform')
#查看转换后分的箱:变成了哑变量
est.fit_transform(X).toarray()


3特征选择

=============================
能够理解业务时:
       根据我们的目标,理解业务用业务常识来选择特征。

不能够理解业务时:
过滤法,嵌入法,包装法,和降维算法。

3.1filter过滤法

=============================
概念:它是根据各种统计检验中的分数以及相关性的各项指标来选择特征。

对象:需要遍历特征或升维的算法

目的:在保持算法表现的前提下,帮助算法们降低计算成本。

3.1.1 VarianceThreshold方差过滤

概念:通过特征本身的方差来筛选特征的类。方差小表示这个特征对于样本区分没有什么作用,可以丢弃。

重要参数threshold

表示方差的阈值,表示舍弃所有方差小于threshold的特征,不填默认为0,即删除所有的记录都相同的特征。
我们只会使用阈值为0或者阈值很小的方差过滤,来为我们优先消除一些明显用不到的特征,然后我们会选择更优的特征选择方法继续削减特征数量。

from sklearn.feature_selection import VarianceThreshold

selector = VarianceThreshold() #实例化,不填参数默认方差为0
'''
我们希望留下一半的特征,那可以设定一个让特征总数减半的方差阈值,只要找到特征方差的中位数
再将这个中位数作为参数threshold的值输入就好了

如何得到方差中位值:取出一半的特征需要多少,可以进行排序观察然后设置值

X = VarianceThreshold(np.median(X.var().values)).fit_transform(X)
'''
X_var0 = selector.fit_transform(X) #获取删除不合格特征之后的新特征矩阵

#快捷写法
X = VairanceThreshold().fit_transform(X)

X_var0.shape

3.1.2相关性过滤

概念:我们希望选出与标签相关且能够为我们提供大量信息的特征。如果特征与标签无关,无用特种浪费内存且可能被认为是噪音
在sklearn当中,我们有三种常用的方法来评判特征与标签之间的相关性:卡方,F检验,互信息。

卡方过滤(分类问题)

卡方检验类:feature_selection.chi2
        计算每个非负特征和标签之间的卡方统计量,并依照卡方统计量由高到低为特征排名。
特征选择类:feature_selection.SelectKBest
      &nbsp可以直接通过输出的统计量来判断我们到底要设置一个什么样的K

注意点:如果卡方检验检测到某个特征中所有的值都相同,会提示我们使用方差先进行方差过滤。

from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#假设在这里我一直我需要300个特征
X_fschi = SelectKBest(chi2, k=300).fit_transform(X_fsvar, y)
X_fschi.shape
超参数K的选取:看P值选择K

在这里插入图片描述
从特征工程的角度,我们希望选取卡方值很大,p值小于0.05的特征,即和标签是相关联的特征

chivalue, pvalues_chi = chi2(X_fsvar,y)#返回的第一个值是卡方值,第二个值是p值

#k取多少?我们想要消除所有p值大于设定值,比如0.05或0.01的特征:
#shape[0]是特征总量,整句代码的意思是把>0.05的部分去掉
k = chivalue.shape[0] - (pvalues_chi>0.05).sum()

X_fschi = SelectKBest(chi2, k=填入上面算出的K).fit_transform(X_fsvar, y)
cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()
F检验(回归&分类)

概念:方差齐性检验,是用来捕捉每个特征与标签之间的线性关系的过滤方法。它即可以做回归也
可以做分类
F检验类:feature_selection.f_classif(分类) & feature_selection.f_regression(回归)

        计算每个非负特征和标签之间的F统计量,并依照卡方统计量由高到低为特征排名。
特征选择类:feature_selection.SelectKBest
      &nbsp可以直接通过输出的统计量来判断我们到底要设置一个什么样的K

注意点:F检验在数据服从正态分布时效果会非常稳定,因此如果使用F检验过滤,我们会先将数据转换成服从正态分布的方式。

F检验的本质是寻找两组数据之间的线性关系,和卡方过滤一样,我们希望选取p值小于0.05或0.01的特征,这些特征与标签时显著线性相关的

from sklearn.feature_selection import f_classif
F, pvalues_f = f_classif(X_fsvar,y)
F
pvalues_f

k = F.shape[0] - (pvalues_f>0.05).sum()
X_fsF = SelectKBest(f_classif, k=填入上面算出的K).fit_transform(X_fsvar, y)
cross_val_score(RFC(n_estimators=10,random_state=0),X_fsF,y,cv=5).mean()```

互信息法(回归&分类)

概念:互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。它既可以做回归也可以做分类,

互信息类:feature_selection.mutual_info_classif(分类) & feature_selection.mutual_info_regression(回归)

        计算每个非负特征和标签之间的F统计量,并依照卡方统计量由高到低为特征排名。
特征选择类:feature_selection.SelectKBest
        可以直接通过输出的统计量来判断我们到底要设置一个什么样的K

注意点:互信息法比F检验更加强大,F检验只能够找出线性关系,而互信息法可以找出任意关系

from sklearn.feature_selection import mutual_info_classif as MIC
result = MIC(X_fsvar,y)
k = result.shape[0] - sum(result <= 0)
X_fsmic = SelectKBest(MIC, k=填写上面算出的k).fit_transform(X_fsvar, y)
cross_val_score(RFC(n_estimators=10,random_state=0),X_fsmic,y,cv=5).mean()

过滤法总结

当统计量判断已经没有特征可以删除时,无论用学习曲线如何跑,删除特征都只会降低模型的表现。
如果数据量太庞大,模型太复杂,我们还是可以牺牲模型表现来提升模型速度,具体看需求。

通常来说,先使用方差过滤,然后使用互信息法来捕捉相关性,不过了解各种各样的过滤方式也是必要的。所有信息被总结在下表,大家自取:
在这里插入图片描述

3.1.3embedded嵌入法

=============================
概念:嵌入法是一种让算法自己决定使用哪些特征的方法先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据权值系数从大到小选择特征。

优点:相比过滤法,嵌入法的结果会更加精确到模型的效用本身,对于提高模型效力有更好的效果。

注意点:模型权值系数就是我们的超参数,我们或许需要学习曲线,或者根据模型本身的某些性质去判断这个超参数的最佳值究竟应该是多少。
嵌入法引入了算法来挑选特征,因此其计算速度也会和应用的算法有很大的关系。如果采用计算量很大,计算缓慢的算法,嵌入法本身也会非常耗时耗力

feature_selection.SelectFromModel

SelectFromModel是一个元变换器,可以与任何在拟合后具有coef_,feature_importances_属性或参数中可选惩罚项的评估器一起使用(比如随机森林和树模型就具有属性feature_importances_,逻辑回归就带有l1和l2惩罚项,线性支持向量机也支持l2惩罚项)。
在这里插入图片描述
我们重点要考虑的是前两个参数。在这里,我们使用随机森林为例

from sklearn.feature_selection import SelectFromModel

from sklearn.ensemble import RandomForestClassifier as RFC

RFC_ = RFC(n_estimators =10,random_state=0)#先要将随机森林实例化才能放入下面SelectModel

X_embedded = SelectFromModel(RFC_,threshold=0.005).fit_transform(X,y)

选读:使用惩罚项的模型的嵌入法
而对于使用惩罚项的模型来说,正则化惩罚项越大,特征在模型中对应的系数就会越小。当正则化惩罚项大到一定的程度的时候,部分特征系数会变成0,当正则化惩罚项继续增大到一定程度时,所有的特征系数都会趋于0。 但是我们会发现一部分特征系数会更容易先变成0,这部分系数就是可以筛掉的。也就是说,我们选择特征系数较大的特征。另外,支持向量机和逻辑回归使用参数C来控制返回的特征矩阵的稀疏性,参数C越小,返回的特征越少。Lasso回归,用alpha参数来控制返回的特征矩阵,alpha的值越大,返回的特征越少。
在算法本身很复杂的时候,过滤法的计算远远比嵌入法要快,所以大型数据中,我们还是会优先考虑过滤法。

3.1.4Wrapper包装法

=============================
概念:包装法与嵌入法十分相似,但不同的是,其使用一个目标函数作为黑盒来帮助我们选取特征,而不是自己输入某个评估指标或统计量的阈值。

区别:过滤法和嵌入法的一次训练解决所有问题,包装法要使用特征子集进行多次训练,因此它所需要的计算成本是最高的。

注意:在这个图中的“算法”不是最终用来导入数据的分类或回归算法(即不是随机森林),而是专业选取最佳特征子集的数据挖掘算法,即我们的目标函数。
在这里插入图片描述
优点:包装法的效果是所有特征选择方法中最利于提升模型表现的,它可以使用很少的特征达到很优秀的效果。

缺点:它比嵌入法算得更见缓慢,所以也不适用于太大型的数据。

feature_selection.RFE

重要参数estimator & n_features_to_select & step

estimator:是需要填写的实例化后的评估器

n_features_to_select是想要选择的特征个数

step:每次迭代中希望移除的特征个数。

重要属性.support_ & .ranking_

.support_:返回所有的特征的是否最后被选中的布尔矩阵
.ranking_:返回特征的按数次迭代中综合重要性的排名

from sklearn.feature_selection import RFE
RFC_ = RFC(n_estimators =10,random_state=0)
selector = RFE(RFC_, n_features_to_select=340, step=50).fit(X, y)
selector.support_.sum()
selector.ranking_
X_wrapper = selector.transform(X)
cross_val_score(RFC_,X_wrapper,y,cv=5).mean()

4特征选择总结

=============================

经验来说,过滤法更快速,但更粗糙。包装法和嵌入法更精确,比较适合具体到算
法去调整,但计算量比较大,运行时间长。

当数据量很大的时候,优先使用方差过滤和互信息法调整,再上其他特征选择方法。

使用逻辑回归时,优先使用嵌入法。使用支持向量机时,优先使用包装法。迷茫的时候,从过滤法走
起,看具体数据具体分析。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值