使用特征选择进行降维

前文讨论了如何在尽可能不丢失特征原始信息的情况下,通过创建新特征矩阵的维度,这种方法被称为特征提取(feature extraction)。本文将学习另一种降维方法:特征选择(feature selection)

特征选择会保留信息量较高的特征而丢失信息量较低的特征。

特征选择的方法可分为三类:过滤器、包装器和嵌入式方法。过滤器方法根据特征的统计信息来选择最优特征。包装器方法通过不断试错,找出一个可以产生高质量预测值的的模型的特征子集。嵌入式方法则将选择最优特征子集作为机器学习算法训练过程的一部分。

一、数值型特征方差的阈值化

从一组数值型特征中移除方差较小的特征。

跳出方差大于给定阈值的特征:

from sklearn import datasets
from sklearn.feature_selection import VarianceThreshold
iris=datasets.load_iris()
features=iris.data
target=iris.target
thresholder=VarianceThreshold(threshold=.5)
features_high_variance=thresholder.fit_transform(features)
features_high_variance[0:3]

方差阈值化(Variance Thresholding,VT)是基本的特征选择方法之一。

方差不是中心化的(它的单位是特征单位的平方),因此如果特征数据集中特征的单位不同,那么VT法就无法起作用。方差的阈值是手动选择的,所以必须依靠人工选择一个合适的阈值。可以通过参数variances_来查看每个特征的方差。

thresholder.fit(features).variances_

如果特征已经标准化(即平均值是0,方差是1),方差阈值将起不到筛选的作用。

二、二值特征的方差阈值化

有一组二值特征数据(即只有两个分类),现在要移除其中方差较小的特征。

from sklearn.feature_selection import VarianceThreshold
features=[[0,1,0],
          [0,1,1],
          [0,1,0],
          [0,1,1],
          [1,0,0]]
thresholder=VarianceThreshold(threshold=(.75*(1-.75)))
thresholder.fit_transform(features)

三、处理高度相关性的特征

使用相关矩阵检查是否存在较高相关性的特征,如果存在,则删除其中一个:

import pandas as pd
import numpy as np
features=np.array([[1,1,1],
                   [2,2,0],
                   [3,3,1],
                   [4,4,0],
                   [5,5,1],
                   [6,6,0],
                   [7,7,1],
                   [8,7,0],
                   [9,7,1]])
dataframe=pd.DataFrame(features)
corr_matrix=dataframe.corr().abs()
#选择相关矩阵的上三角矩阵
upper=corr_matrix.where(np.triu(np.ones(corr_matrix.shape),k=1).astype(np.bool_))
#找到相关性大于0.95的特征列的索引
to_drop=[column for column in upper.columns if any(upper[column]>0.95)]
dataframe.drop(dataframe.columns[to_drop],axis=1).head(3)

如果两个特征高度相关,那么它们所包含的信息就非常相似,因此这两个特征就存在冗余。

首先创建一个所有特征的相关矩阵:

如何从相关矩阵的上三角阵中找出相关性高的特征对:

最后从每一对高度相关的特征中删除一个。

四、删除与分类任务不相关的特征

对于分类型特征,计算每个特征和目标向量的卡方统计量:

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2,f_classif
iris=load_iris()
features=iris.data
target=iris.target
#将分类数据转换成整数型数据
features=features.astype(int)
#选择卡方统计量最大的两个特征
chi2_selector=SelectKBest(chi2,k=2)
features_kbest=chi2_selector.fit_transform(features,target)
print("Original number of features:",features.shape[1])
print("Reduced number of features:",features_kbest.shape[1])

对于数值型特征数据,则计算每个特征与目标向量之间的方差分析F值(ANOVA F_value)

#选择F值最大的两个特征
fvalue_selector=SelectKBest(f_classif,k=2)
features_kbest=fvalue_selector.fit_transform(features,target)
print("Oringinal number of features:",features.shape[1])
print("Reduced number of features:",features_kbest.shape[1])

除了固定数量的特征,还可以通过SelectPercentile方法来选择n%的特征:

from sklearn.feature_selection import SelectPercentile
#选择F值位于前75%的特征
fvalue_selector=SelectPercentile(f_classif,percentile=75)
features_kbest=fvalue_selector.fit_transform(features,target)
print("Oringinal number of features:",features.shape[1])
print("Reduced number of features:",features_kbest.shape[1])

卡方检验就是统计样本的实际观测值与理论推断值之间的偏离程度,如果卡方值(χ²)越大,二者偏差程度越大;反之,二者偏差越小。使用卡方统计时,所有值都必须是非负的。

卡方统计的结果是一个数字,它代表观察值和期望值(假设特征与目标向量无关时的值)之间的差异。通过计算特征和目标向量的卡方统计量,我们可以得到对两者之间独立性的度量值。如果两者相互独立,就代表特征与目标向量无关,特征中不包含分类所需的信息。

对于数值型特征还可以使用f_classif来计算每个特征和目标向量间的ANOVA F值。在根据目标向量对数值型特征分类时,该值可以用来判断每个分类的特征均值之间的差异有多大。

五、递归式特征消除

使用scikit-learn的RFECV类通过交叉验证(Crossing Validation,CV)进行递归式特征消除(Recursive Feature Elimination,REF)。该方法会重复训练模型,每一次训练消除一个特征,知道模型性能(例如精度)变差。剩余的特征就是最优特征:

import warnings
from sklearn.datasets import make_regression
from sklearn.feature_selection import RFECV
from sklearn import datasets,linear_model
#忽略一些烦人但无害的警告信息
warnings.filterwarnings(action="ignore",module="scipy",
                        message="^internal gelsd")
features,target=make_regression(n_samples=10000,n_features=100,
                                n_informative=2,random_state=1)
#创建线性回归对象
ols=linear_model.LinearRegression()
#递归消除特征
rfecv=RFECV(estimator=ols,step=1,scoring="neg_mean_squared_error")
rfecv.fit(features,target)
rfecv.transform(features)

执行完RFE后,就可以得到应该保留的特征数量:

也可以查看哪些特征应该被保留:

rfecv.support_

甚至可以查看特征的排名:

rfecv.ranking_

RFE背后的思想是重复训练一个包含若干参数(权重或系数)的模型,如线性回归或支持向量机。

RFE首先会使用所有的特征训练模型,然后找出具有最小参数的特征(这代表该特征不重要),并将它从特征集中移除。注意,在该方法中我们假设特征已经标准化处理。

应该保留多少特征?我们可以重复这个循环,直到只剩下最后一个特征。另一个选择是引入一种被称为交叉验证(CV)的方法。

假设有两种数据:要预测的目标向量和特征矩阵。第一步,将数据分为两组:训练集和测试集。第二步,使用训练集来训练模型。第三步,假装不知道测试集的目标向量(预测结果),将模型应用于测试集的特征,得到测试集的预测结果。最后,将测试集的预测结果和真实值进行比较,以评估模型性能。

可以通过交叉验证方法计算出RFE期间需要保留的最优特征数量。具体做法:在每次RFE迭代中,使用交叉验证来评估模型。如果交叉验证显示在减少一个特征后模型的性能有所改进,则继续下一次循环。如果交叉验证显示在丢弃某个特征后模型的性能变差,则将该特征重新加入到特征集,并选择这些特征作为最优特征。

参数estimator决定训练模型的类型(如线性回归),参数step决定每次迭代丢弃的特征的数量或比例,参数scoring决定在做交叉验证时评估模型性能的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值