利用特征选择进行特征降维

特征提取(feature extraction):在尽可能不丢失特征原始信息的情况下,通过创建新特征来降低特征矩阵的维度。

另一种降维方法,特征选择会保留信息量较高的特征而丢弃信息量较低的特征。

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

1. 数值型特征方差的阈值化

问题描述:从一组数值型特征中移除方差较小(即可能包含的信息较少)的特征。

解决方案:挑出方差大于给定阈值的特征

from sklearn import datasets
from sklearn.feature_selection import VarianceThreshold
#加载数据
iris = datasets.load_iris()
#创建features和target
features = iris.data
target = iris.target
#创建VarianceThreshold
threshold = VarianceThreshold(threshold = 0.5)
#创建大方差特征矩阵
features_high_variance = threshold.fit_transform(features)
#显示大方差特征矩阵
features_high_variance[0:3]
outputs:
array([[5.1, 1.4, 0.2],
       [4.9, 1.4, 0.2],
       [4.7, 1.3, 0.2]])

方差阈值化(Variance Thresholding,VT)是最基本的特征选择方法之一。此方法依据是小方差的特征可能比大方差的特征的重要性低一些。

  • 注意点:
    • 方差不是中心化的,因此如果特征数据集中特征的单位不同,那么VT就无法起作用。
    • 方差的阈值是手动选择的,所以必须依靠人工来选择一个合适的阈值。可以通过参数variance_来查看每个特征的方差:VarianceThreshold().fit(features).variances_
    • 如果特征已经标准化,方差阈值将起不到筛选的作用。

2. 二值特征的方差阈值化

问题描述:有一组而知特征数据,要移除其中方差较小的特征。

解决方案:挑出方差给定阈值的二值特征。

from sklearn.feature_selection import VarianceThreshold
#创建特征矩阵
features = [[0,1,0],
            [0,1,1],
            [0,1,0],
            [0,1,1],
            [1,0,0]]
#创建VarianceThreshold对象并运行
thresholder = VarianceThreshold(threshold = (0.75 * (1-0.75)))
thresholder.fit_transform(features)
output:
array([[0],
       [1],
       [0],
       [1],
       [0]])

和数值型特征一样,挑选高信息量的分类特征的方法之一就是查看它们的方差。在二值特征(即伯努利随机变量)中,方差的计算方式如下:

V a r ( x ) = p ( 1 − p ) Var(x) = p(1-p) Var(x)=p(1p)
其中p是观察值属于1个分类的概率。通过设置p的值,可以删除大部分观察值都属于同一个类别的特征。

3. 处理高度相关性的特征

问题描述:特征矩阵中的某些特征具有较高的相关性

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

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
dataframe = pd.DataFrame(features)
print(dataframe)
#创建相关矩阵
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(5)
#output:
0	2
0	1	1
1	2	0
2	3	1
3	4	0
4	5	1

4. 删除与分类任务不相关的特征

问题描述:根据分类的目标向量,删除信息量较低的特征

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

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])

output:

original number of features: 4
Reduced number of features: 2

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

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)
#选择F值最大的两个特征
fvalue_selector = SelectKBest(f_classif,k = 2)
features_kbest = fvalue_selector.fit_transform(features,target)
#显示结果
print("original number of features:",features.shape[1])
print("Reduced number of features:",features_kbest.shape[1])

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

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2,f_classif
from sklearn.feature_selection import SelectPercentile
#加载数据
iris = load_iris()
features = iris.data
target = iris.target
#将分类数据转换成整数型数据
features = features.astype(int)
#选择F值位于75%的两个特征
fvalue_selector = SelectPercentile(f_classif, percentile = 75)
features_kbest = fvalue_selector.fit_transform(features,target)
#显示结果
print("original number of features:",features.shape[1])
print("Reduced number of features:",features_kbest.shape[1])

output:

original number of features: 4
Reduced number of features: 3

卡方统计可以检查两个分类向量的相互独立性。也就是说,卡方统计量代表了观察到的样本数量和期望的样本数量(假设特征与目标向量无关)之间的差异。

通过计算特征和目标向量的卡方统计量,可以得到对两者之间独立性的度量值。如果两者相互独立,就代表特征与目标向量无关,特征中不包含分类所需要的信息。相反,如果特征和目标向量高度相关,则代表特征中包含训练分类模型所需的很多信息。

5. 递归式特征消除

问题描述:自动选择需要保留的最优特征。

解决方案:使用sklearn的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="ingore",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)
#最优特征数量
rfecv.n_features_
#最优特征
rfecv.support_
#将特征从最好到最差排序
rfecv.ranking_

猜你喜欢

转载自blog.csdn.net/weixin_44127327/article/details/108600365