数据处理和特征工程(二)

4. 特征选择

一般有四种方法用来选择特征:过滤法、嵌入法、包装法、降维算法

4.1 Filter过滤法**

根据统计检验的分数和相关性指标来选择特征,完全独立于各种机器学习算法

4.1.1 方差过滤VarianceThreshold

通过特征本身的方差来筛选类,如果一个特征的方差很小,说明样本在这个特征上基本没有差异,可能大多数值都一样。
VarianceThreshold有重要参数Threshold,表示舍弃所有方差小于threshold的特征,不填默认为0,删除所有记录相同的特征。
过滤法的主要对象是:需要遍历特征或者升维的算法,而过滤法的主要目的是,在维持算法表现得前提下,帮助算法们降低计算成本
现实中,我们只会使用阈值为0或者阈值很小得方差过滤,消除一些明显用不到得特征,然后会选择更优得特征选择方法继续削减特征数量

4.1.2 代码示例

from sklearn.feature_selection import VarianceThreshold
import numpy as np

x_var0 = VarianceThreshold.fit_transform(x)
x_fsvar = VarianceThreshold().fit_trainsform(x)
x_fsvar.shape

4.2 相关性过滤【卡方过滤】

4.2.1 相关性过滤

卡方过滤是专门针对离散型标签得过滤方法。计算每个非负特征和标签之间得卡方统计,并依照卡方统计量由高到低为特征排名,再依据排名选出前k个分数最高得特征得类
如果卡方检验检测到某个特征中所有值都相同,会提示我们先进行方差过滤

4.2.2 代码示例

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  # 卡方检验统计量

# 假设我们需要选出前200个分数最高得特征
# x_fvar为使用方差过滤后的x特征矩阵
x_fschi = SelectKBest(chi2,k=200).fit_transform(x_fvar,y)
x_fschi

这里得k如果使模型得效果降低了,就说明k值设得太小了,我们需要重新调整k值,或者放弃卡方过滤。 卡方检验得本质是推测两组数据之间得差异,其检验得原假设是“两组数据是相互独立得”,卡方检验返回卡方值和P值,其中卡方值很难界定有效得范围,而P值,我们一般使用0.01或0.05作为显著性水平,就是p值得判断边界。当p<0.05或0.01时,两组数据是相关得,反之,两组数据相互独立

chivalue,pvalues_chi = chi2(x_fvar,y)  # 结果返回卡方值和p值

# 我们想要消除所有p值大于设定值得特征
k = chivalue.shape[0] - (pvalues_chi > 0.05).sum()

4.3 F检验过滤

F检验过滤是通过捕捉每个特征与标签之间的线性关系的过滤方法,F检验既可以做回归也可以做分类。

  • feature_selection.f_classif F检验分类
  • feature_selection.f_regression F检验回归

F检验在数据服从正态分布时效果会比较稳定,因此需要先将数据转换成服从正态分布的方式
和卡方过滤一样,我们希望选取p值小于0.05或0.01的特征,这些特征与标签是显著线性相关的,p>0.05或者0.01的特征则被我们认为没有线性相关关系,应该被删除

from sklearn.feature_selection import f_classif

# 返回F值和P值
F,pvalues_f = f_classif(x_fsvar,y)
k = F.shape[0] - (pvalues_f > 0.05).sum()

4.4 互信息法

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

  • feature_selection.mutual_info_classif
  • feature_selection.mutual_info_regression
from sklearn.feature_selection import mutual_info_classif as MIC

result = MIC(x_fsvar,y)
k = result.shape[0] - sum(result <= 0)

4.5 嵌入法**

让算法自己决定使用哪些特征的方法,即特征选择和算法训练同时进行。
用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据权值系数从大到小选择特征。比如决策树返回的feature_importances。
嵌入法的计算速度和计算量会基于所选择的算法
在sklearn中使用SelectFromModel来完成嵌入法的使用,其含有estimator和threshold两个参数

  • estimator : 使用的模型评估器
  • threshold :特征重要性的阈值,重要性低于这个阈值的特征都将被删除
# 使用随机森林作为示例
from sklearn.feature_selection import SelectFromModel   # 导入SelectFromModel
from sklearn.ensemble import RandomForestClassifier as RFC
import numpy as np
import matplotlib.pyplot as plt

RFC_ = RFC(n_estimators=10,random_state=0)  # 随机森林的实例化
x_embedded = SelectFromModel(RFC_,threshold=0.005).fit_transform(x,y)   
x_embedded.shape

# 使用学习曲线来考察最佳阈值
RFC_.fit(x,y).feature_importances_
threshold = np.linspace(0,(RFC_.fit(x,y).feature_importances_).max(),20)

score =[]
for i in threshold:
    x_embedded = SelectFormModel(RFC_,threshold=i).fit_transform(x,y)
    once = cross_val_score(RFC_,x_embedded,y,cv=5).mean()
    score.append(once)
plt.plot(threshold,score)
plt.show()

4.6 包装法

与嵌入法十分相似,也是特征选择和算法训练同时进行的方法。它会帮我们选择一个目标函数来选取特征【不用我们自己选择】 包装法每次递归都会删除一些特征,因此计算成本要低于嵌入法
在sklearn中实现包装法使用RFE

  • n_features_to_select:想要选择的特征个数
  • .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)  # 选择340个特征

selector.support_.sum()  # 返回所有特征中的布尔矩阵【查看被选中和没有被选中的特征】
selector.ranking_        # 返回特征的按数次迭代中综合重要性的排名
x_wrapper = selector.transform(x)

# 使用学习曲线选择最好的n_features_to_select
score = []
for i in range(1,751,50):
   x_wrapper = RFE(RFC_,n_features_to_select=i,step=50).fit(x,y)
   once = cross_val_score(RFC_,x_wrapper,y,cv=5).mean()
   score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(1,751,50),score)
plt.xticks(range(1,751,50))
plt.show()
  • 数据量很大时,优先使用方差法过滤和互信息法调整,再上其他特征选择方法
  • 使用逻辑回归时,优先使用嵌入法
  • 使用支持向量机时,优先使用包装法

5. 降维算法PCA

算法中的降维指的是降低特征的数目,降维的目的是为了让算法运算更快,效果更好

5.1 主成分分析PCA

在降维中,PCA使用的信息衡量指标就是样本方差,又称可解释性方差,方差越大,特征所带的信息越多,让数据能够压缩到少数特征上并且总信息量不损失太多的技术就是矩阵分解,PCA找到的每个新特征向量就叫做“主成分”,而被丢弃的特征向量很有可能就是噪音

PCA和特征选择的区别?
特征选择是从已存在的特征中选取携带信息最多的,选完之后的特征依然具有可解释性。而PCA是对已存在的特征进行压缩,降维完毕后的特征不是原本特征的任何一个。新特征矩阵不具有可解释性。因此PCA一般不适用于探索特征和标签之间关系的模型【线性回归】,在线性回归中使用特征选择

5.1.1 PCA基本参数

  • n_components:降维后的维度。只是需要人为设定的超参数,并且设定的数字会影响模型的表现,n_componnents需要设定一个合理的值,不能太大也不能太小
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import numpy as np

# 导入数据
iris = load_iris()
x = iris.data
y = iris.target

pca = PCA(n_components=2)  # 降到2维
x_ = pca.fit_transform(x)
x_  # 降维后的特征矩阵

# explained_variance_ 查看降维后每个新特征向量上所带的信息量大小【可解释性反差的大小】
pca.explained_variance_

# explained_variance_ratio_ 查看降维后每个新特征所占的信息占原始数据总信息的百分比【可解释性方差贡献率】
pca.explained_variance_ratio_
pca.explained_variance_ratio_.sum()

# 可视化
pca_line = PCA().fit(x)
plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks([1,2,3,4])
plt.xlabel('number of components after dimension reduction')
plt.ylabel('cumulative explained variance')
plt.show()
  • n_components:按信息量占比选参数,输入[0,1]之间的浮点数,让参数svd_solver=='full',表示希望降维后的总解释性方差占比大于指定的百分比。比如,输入n_components = .97,PCA会自动选出能够保留的信息超过97%的特征数量
pca_f = PCA(n_components=.99,svd_solver='full')
pca_f = pca_f.fit(x)

5.1.2 PCA中的SVD

SVD是奇异值分解器的意思
SVD有一种非常简便的计算过程,不计算协方差矩阵,直接找到新特征向量组成的n维空间。简单来说,SVD在矩阵分解的过程中比PCA简单快速。SVD中衡量特征的指标是奇异值。在PCA中,使用SVD的性值来减少计算量,并让信息的评估指标是方差
重要参数

  • svd_solver:用来控制矩阵分解的一些细节的参数,有四种模式可以选择'auto','full','arpack','randomized',默认值是auto
    • auto:基于x.shape和n_components的默认策略来选择分解器。如果数据维度太高,则会选择效率更高的randomized,如果数据维度适中,则会使用full
    • full:会生成完整的SVD,适合数据量适中且计算时间充足的情况
    • arpack:可以加快运算速度,适合特征矩阵很大的时候,但一般用于特征矩阵为稀疏矩阵的情况
    • randomized:适合特征矩阵巨大,计算量庞大的情况
  • random_state:random_state 在参数svd_solver 为randomized或arpark时生效,选“auto”即可
pca_f = PCA(n_components=.99,svd_solver='full')
pca_f = pca_f.fit(x)
pca_f.explained_variance_ratio_.sum()

你可能感兴趣的:(数据处理和特征工程(二))