数据分析之特征工程——Filter过滤法

弓背霞明剑照霜,秋风走马出咸阳。这篇文章主要讲述数据分析之特征工程——Filter过滤法相关的知识,希望能为你提供帮助。
前言上篇文章我们给大家介绍了数据分析的前期工作——??数据预处理??。本文给大家介绍的是预处理之后的下一个环节,就应该需要我们对预处理好后的数据进行特征工程分析,由于特征工程是一个比较大的步骤,内容比较繁多,为了方便大家更有效率的学习和理解,本文首先介绍的就是特征工程中的第一个步骤——Filter过滤法。
一、特征工程简介当数据预处理完成后,我们接下来就需要进行特征工程的相关处理了,以下是特征工程、特征选择以及特征创造的需要做的相关事项,具体如下:

我们在做特征工程之前,首先需要做的就是要充分理解数据的来源以及对数据要很熟悉。技术能够让模型起飞,前提是你和业务人员一样理解数据。所以特征选择的第一步,其实是根据我们的目标,用业务常识来选择特征。来看??上篇文章???中用到的完整版??泰坦尼克号??数据中的这些特征:

其中是否存活是我们的标签。很明显,以判断“是否存活”为目的,票号,登船的舱门,乘客编号明显是无关特征,可以直接删除。姓名,舱位等级,船舱编号,也基本可以判断是相关性比较低的特征。性别,年龄,船上的亲人数量,这些应该是相关性比较高的特征。所以,特征工程的第一步是:理解业务。
当然了,在真正的数据应用领域,比如金融,医疗,电商,我们的数据不可能像泰坦尼克号数据的特征这样少,这样明显,那如果遇到极端情况,我们无法依赖对业务的理解来选择特征,该怎么办呢?我们有四种方法可以用来选择特征:过滤法,嵌入法,包装法和降维算法。本文为大家首先介绍的就是Filter过滤法。在介绍之前,我们首先介绍今天需要用到的数据,今天的数据集是这样的:
【数据分析之特征工程——Filter过滤法】
这个数据集就是我们在机器学习中经典的数字识别的数据集digit recognizor,大家需要的话可以在评论区找我,单独发给大家哈!我们将这个数据集命名为??digit recognizor.csv??,然后与我们的代码放在同一层目录下,本文的数据集是放在这个位置:

接下来我们稍微对该数据做一个相关的处理预分析:

import pandas as pd
data = https://www.songbingjia.com/android/pd.read_csv("digit recognizor.csv")
print(data.shape)
X = data.iloc[:,1:]
y = data.iloc[:,0]
print(X.shape)
print(y.shape)

具体我们分析的结果如下:

有了这些介绍与数据的分析,接下来,我们给大家正式介绍Filter过滤法。
二、Filter过滤法过滤方法通常用作预处理步骤,特征选择完全独立于任何机器学习算法。它是根据各种统计检验中的分数以及相关性的各项指标来选择特征。具体的过程如下:

1 、方差过滤
方差过滤主要会用到??VarianceThreshold??,具体的相关内容如下:

这是通过特征本身的方差来筛选特征的类。比如一个特征本身的方差很小,就表示样本在这个特征上基本没有差异,可能特征中的大多数值都一样,甚至整个特征的取值都相同,那这个特征对于样本区分没有什么作用。所以无论接下来的特征?程要做什么,都要优先消除方差为0的特征。
VarianceThreshold有重要参数threshold,表示方差的阈值,表示舍弃所有方差小于threshold的特征,不填默认为0,即删除所有的记录都相同的特征。我们通过一段代码看看其实现的效果,具体代码如下:
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
data = https://www.songbingjia.com/android/pd.read_csv("digit recognizor.csv")
X = data.iloc[:,1:]
y = data.iloc[:,0]
VTS = VarianceThreshold() #实例化,不填参数默认?差为0
X_var0 = VTS.fit_transform(X) #获取删除不合格特征之后的新特征矩阵
print(X_var0.shape)

具体的处理结果如下:

从上面的处理结果可以看出,我们已经删除了方差为0的特征,但是依然剩下了708多个特征,明显还需要进一步的特征选择。然而,如果我们知道我们需要多少个特征,方差也可以帮助我们将特征选择一步到位。比如说,我们希望留下一半的特征,那可以设定一个让特征总数减半的方差阈值,只要找到特征方差的中位数,再将这个中位数作为参数??threshold??的值输入就好了,具体实现如下:
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
import numpy as np
data = https://www.songbingjia.com/android/pd.read_csv("digit recognizor.csv")
X = data.iloc[:,1:]
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X)
print(X_fsvar.shape)

具体的处理结果如下:

从上面的处理结果发现,这次的特征就少了许多,如果想要查看具体哪些特征被保留下来了呢?我们可以做如下的操作:
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
import numpy as np
data = https://www.songbingjia.com/android/pd.read_csv("digit recognizor.csv")
X = data.iloc[:,1:]
VTS = VarianceThreshold(np.median(X.var().values)) #实例化
VTS = VTS.fit(X) #训练模型
X_fsvar = VTS.transform(X) #将X降维,只保留需要的特征
#查看模型相关接?
VTS.get_support(indices=False)
#返回与原特征?度相等的布尔索引,被留下的特征为True
VTS.get_support(indices=True)
#提取出所有满?要求的特证名
print(X.columns[VTS.get_support(indices=False)])
print(X.columns[VTS.get_support(indices=True)])
#提取出满?要求的特征矩阵
#以下两种表达都可以
print(X.iloc[:,VTS.get_support(indices=True)])
print(X.loc[:,VTS.get_support()])

具体执行结果如下:


我们进行方差过滤之后,对模型效果会有怎样的影响呢?在这里,我为?家准备了KNN和随机森林分别在方差过滤前和方差过滤后运行的效果和运行时间的对比。KNN是K近邻算法中的分类算法,其原理非常简单,是利用每个样本到其他样本点的距离来判断每个样本点的相似度,然后对样本进行分类。KNN必须遍历每个特征和每个样本,因而特征越多,KNN的计算也就会越缓慢。接下来我们就去实现这两种方法的对比。
首先就是模块的导入以及数据的准备
import pandas as pd
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import VarianceThreshold
import numpy as np
data = https://www.songbingjia.com/android/pd.read_csv("digit recognizor.csv")
X = data.iloc[:,1:]
y = data.iloc[:,0]
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X)
print(X_fsvar)

具体的执行结果如下:

我们从模块??neighbors???导入??KNeighborsClassfier???缩写为??KNN???,导入??随机森林???缩写为??RFC???,然后导入??交叉验证模块???和??numpy???。其中未过滤的数据是X和y,使用中位数过滤后的数据是??X_fsvar??,这些都是我们之前已经运行过的代码。
KNN方差过滤前数据运行情况
import pandas as pd
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.neighbors import KNeighborsClassifier

    推荐阅读