机器学习手册学习笔记--使用特征选择进行降维

251 阅读3分钟

仅供自己复习回顾使用,若有侵权可删除

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

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

数值型特征方差的阈值化

如果特征数据集中特征的单位不同(例如,一个特征以年为单位,而另一个特征以美元为单位),那么 VT 法就无法起作用;

如果特征已经标准化(即平均值为 0,方差为 1),方差阈值将起不到筛选的作用(因为这时特征的方差全部为 1)

# 加载库
from sklearn import datasets
from sklearn.feature_selection import VarianceThreshold
iris = datasets.load_iris()
# 创建 features 和 target
features = iris.data
target = iris.target

# 创建 VarianceThreshold 对象
thresholder = VarianceThreshold(threshold=.5)
# 创建大方差特征矩阵
features_high_variance = thresholder.fit_transform(features)
# 显示大方差特征矩阵
features_high_variance[0:3]
# 显示方差
thresholder.fit(features).variances_

二值特征的方差阈值化

Var(x)=p(1-p)

可以删除大部分观察值都属于同一个类别的特征

from sklearn.feature_selection import VarianceThreshold
# 用如下信息创建特征矩阵 :
# 特征 0: 80% 为分类 0
# 特征 1: 80% 为分类 1
# 特征 2: 60% 为分类 0, 40% 为分类 1
features = [[0, 1, 0],
            [0, 1, 1],
            [0, 1, 0],
            [0, 1, 1],
            [1, 0, 0]]
# 创建 VarianceThreshold 对象并运行
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
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值

# 选择F值最大的两个特征
fvalue_selector = SelectKBest(f_classif, k=2) #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])

递归式特征消除

该方法会重复训练模型,每一次训练移除一个特征,直到模型性能(例如精度)变差。剩余的特征就是最优特征

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")
#参数 estimator 决定训练模型的类型(如线性回归),
#参数 step 决定每次迭代丢弃的特征的数量或比例,
#参数 scoring 决定在做交叉验证时评估模型性能的方法。
rfecv.fit(features, target)
rfecv.transform(features)
#保留的特征数量
rfecv.n_features_
# 哪些特征是最优特征
rfecv.support_
# 将特征从最好到最差排序
rfecv.ranking_