目录
-
过滤法(Filter Methods):
- 方差选择法:移除方差低于阈值的特征。
- 相关系数法:计算特征与目标变量之间的相关性,选择相关性高的特征。
-
包裹法(Wrapper Methods):
- 递归特征消除(RFE):递归地训练模型,删除权重系数较小的特征。
- 前向选择:从空特征集开始,逐步添加特征,直到模型性能不再显著提升。
- 后向消除:从全特征集开始,逐步删除特征,直到模型性能不再显著下降。
-
嵌入法(Embedded Methods):
- 基于正则化的方法,如Lasso回归,可以通过控制正则化参数λ来实现特征选择。
- 决策树和随机森林等方法通过计算特征重要性来进行特征选择。
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectKBest, f_classif, RFE
from sklearn.linear_model import LassoCV
# 读取数据
root_path = "D:/learnt/python/ai-learn/Natural language processing/kaggle/Classification with an Academic Success"
data = pd.read_csv(root_path + '/train.csv') # 替换为实际数据文件路径
# 数据预处理
X = data.drop(['id', 'Target'], axis=1) # 特征
y = data['Target'] # 目标变量
# # 将目标变量进行标签编码
target_list = set(list(y)) # 去掉重复的标签
print(target_list)
target_dict = {key: num for num, key in enumerate(target_list)} # 制作标签字典
print(f"标签编码字典:{target_dict}")
y = [target_dict[i] for i in y] # 将标签编码
print(f"转化后的部分标签:{y[0:5]}")
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 过滤法:方差选择法
from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(threshold=0.1)
X_var = selector.fit_transform(X_train)
print("\n过滤法:方差选择法:\n", X_var)
# 过滤法:相关系数法
selector = SelectKBest(f_classif, k=10)
X_best = selector.fit_transform(X_train, y_train)
print("\n过滤法:相关系数法:\n", X_best)
# 包裹法:递归特征消除(RFE)
rfe = RFE(estimator=RandomForestClassifier(), n_features_to_select=10, step=1)
X_rfe = rfe.fit_transform(X_train, y_train)
print("\n包裹法:递归特征消除(RFE):\n", X_rfe)
# 嵌入法:Lasso回归
lasso = LassoCV()
lasso.fit(X_train, y_train)
importance = np.abs(lasso.coef_)
feature_names = X_train.columns
selected_features = feature_names[importance > 0]
print("\n嵌入法:Lasso回归:\n", selected_features)
# 嵌入法:随机森林
model = RandomForestClassifier()
model.fit(X_train, y_train)
importances = model.feature_importances_ # 得到每个特征对于标签的重要性
indices = np.argsort(importances)[::-1] # 特征重要性进行升序
print("Feature ranking:")
for f in range(X_train.shape[1]):
print("%d. feature %s (%f)" % (f + 1, X_train.columns[indices[f]], importances[indices[f]]))
一.过滤法
方差选择法原理:
方差选择法是一种特征选择的简单方法,它根据特征的方差来进行选择。其基本原理如下:
- 方差定义:方差是衡量数据分布离散程度的指标,方差越大表示数据的变化越大,反之表示变化不大。
- 方差选择法:在方差选择法中,我们计算每个特征的方差,并将方差低于设定阈值的特征视为低方差特征,从而移除这些特征。这是基于假设:低方差的特征对于预测目标变量的贡献较小,可能只包含噪声或者信息量不足的特征。
具体步骤如下:
- 计算每个特征的方差。
- 设定一个方差的阈值,通常通过经验或者领域知识来选择。
- 过滤掉方差低于阈值的特征,保留方差高于阈值的特征。
# 过滤法:方差选择法
from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(threshold=0.1)
X_var = selector.fit_transform(X_train)
- 引入了
VarianceThreshold
类,这是 sklearn.feature_selection 模块中用于方差选择法的工具。方差选择法是一种简单的特征选择方法,用于过滤掉方差低于阈值的特征。 VarianceThreshold(threshold=0.1)
创建了一个VarianceThreshold
对象,指定了方差的阈值为0.1
。selector.fit_transform(X_train)
对训练集X_train
进行特征选择操作,返回经过选择后的特征矩阵X_var
。这里会自动根据方差阈值过滤掉方差低于0.1
的特征。
结果图:
方差选择法的优点在于简单直观,计算速度快。但需要注意,它假设特征的方差越大,其对目标变量的贡献越大,这种假设不一定适用于所有情况。因此,在应用方差选择法时,需要根据具体问题和数据集来合理选择方差阈值,或者结合其他特征选择方法来提高模型的性能和泛化能力。
相关性系数法原理:
代码解释:
selector = SelectKBest(f_classif, k=10)
X_best = selector.fit_transform(X_train, y_train)
print("\n过滤法:相关系数法:\n", X_best)
-
SelectKBest
是 sklearn.feature_selection 模块中的一个类,用于根据指定的评分函数选择前 k 个最佳特征。在这里,评分函数f_classif
是用于分类问题的方差分析(ANOVA)F统计量。 -
k=10
指定了选择前 10 个最佳特征。 -
selector.fit_transform(X_train, y_train)
对训练集X_train
和对应的目标变量y_train
进行拟合和转换操作。具体来说,它会计算每个特征与目标变量之间的相关性,并选择评分最高的 k 个特征。 -
X_best
是经过选择后的特征矩阵,仅包含了相关性最高的 10 个特征。 -
print("\n过滤法:相关系数法:\n", X_best)
打印输出选择后的特征矩阵X_best
。
结果图:
相关性系数法(Correlation-based feature selection)是一种基于特征与目标变量之间相关性的特征选择方法。它的原理如下:
-
评分函数选择:在相关性系数法中,我们首先选择一个适当的评分函数,用于度量每个特征与目标变量之间的相关性。常见的评分函数包括 Pearson 相关系数、Spearman 相关系数等。在分类问题中,常用的评分函数是方差分析(ANOVA)F统计量 (
f_classif
),它用于衡量特征在不同类别之间的方差。 -
特征选择:根据选择的评分函数,计算每个特征与目标变量之间的相关性得分。得分越高表示特征与目标变量之间的关系越显著。
-
选择前 k 个特征:在给定的 k 值(如
k=10
)下,选择评分最高的 k 个特征作为最终的特征集合。这些特征被认为对目标变量的预测有重要贡献,因此被保留下来用于建模。 -
应用场景:相关性系数法通常用于数据集中特征较多的情况下,帮助减少特征空间的维度,提高模型训练效率和泛化能力。通过选择与目标变量高度相关的特征,可以更有效地捕捉数据中的关键模式,提升模型的预测性能。
总之,相关性系数法通过评估特征与目标变量之间的相关性来进行特征选择,是一种常用且有效的特征选择方法之一,适用于各种分类和回归问题中的特征筛选任务。
二.包裹法
递归特征消除(RFE)原理:
rfe = RFE(estimator=RandomForestClassifier(), n_features_to_select=10, step=1)
X_rfe = rfe.fit_transform(X_train, y_train)
print("\n包裹法:递归特征消除(RFE):\n", X_rfe)
-
RFE
是 sklearn.feature_selection 模块中的一个类,用于递归地选择特征,通过在每一步选择中排除最不重要的特征来实现。这种方法利用了模型的性能来选择特征,属于包裹法的一种。 -
estimator=RandomForestClassifier()
指定了用于评估特征重要性的模型估计器。在这里,选择了随机森林分类器作为评估器。 -
n_features_to_select=10
指定了要选择的特征数量,即最终保留的特征数目。 -
step=1
指定了每次迭代中要移除的特征数量。在每一轮中,它会移除一个特征,直到达到n_features_to_select
指定的数量。 -
rfe.fit_transform(X_train, y_train)
对训练集X_train
和对应的目标变量y_train
进行递归特征消除操作,并返回经过选择后的特征矩阵X_rfe
。 -
print("\n包裹法:递归特征消除(RFE):\n", X_rfe)
打印输出经过递归特征消除后的特征矩阵X_rfe
。
结果图:
递归特征消除(RFE)是一种通过反复构建模型并选择性地移除最不重要特征的方法来进行特征选择的技术。它的原理如下:
-
模型训练:首先,选择一个用于评估特征重要性的机器学习模型(在这里是随机森林分类器)。初始时,使用所有的特征来训练模型。
-
特征重要性评估:通过训练好的模型,可以获得每个特征的重要性得分。在分类问题中,常用的重要性评分包括基于树模型的特征重要性评估。
-
特征消除:根据特征的重要性,每次迭代中,移除最不重要的若干个特征(步长由
step
控制),直到达到预设的特征数量n_features_to_select
。 -
性能评估:在每一轮中,都会重新训练模型,并评估其性能。通常,使用交叉验证或者留出法来评估模型的性能。
-
最终特征集合:最终,保留了在所有迭代中被判定为重要的特征。
递归特征消除的优点在于它考虑了特征之间的交互影响,能够更精确地选择出对模型预测性能贡献最大的特征子集。然而,它的计算开销较大,因为需要多次训练模型,特别是在特征较多的情况下。
总结来说,RFE 是一种强大的特征选择方法,特别适用于那些模型性能高度依赖于特征选择的情况下,能够帮助提高模型的泛化能力和解释性。
三.嵌入法
嵌入法:Lasso回归原理:
lasso = LassoCV()
lasso.fit(X_train, y_train)
importance = np.abs(lasso.coef_)
feature_names = X_train.columns
selected_features = feature_names[importance > 0]
print("\n嵌入法:Lasso回归:\n", selected_features)
-
LassoCV
是 sklearn.linear_model 模块中的一个类,它使用 L1 正则化(Lasso)来进行特征选择,并且通过交叉验证来确定正则化参数的大小。 -
lasso.fit(X_train, y_train)
对训练集X_train
和对应的目标变量y_train
进行 Lasso 回归拟合。 -
importance = np.abs(lasso.coef_)
获取了拟合后的 Lasso 模型的系数(特征的权重),并取了其绝对值,以获得特征的重要性。 -
feature_names = X_train.columns
获取了训练集中的特征名称。 -
selected_features = feature_names[importance > 0]
根据 Lasso 回归的系数,选择那些系数绝对值大于 0 的特征,也就是被模型选中的特征。 -
print("\n嵌入法:Lasso回归:\n", selected_features)
打印输出被 Lasso 回归选中的特征集合。
结果图:
Lasso 回归是一种使用 L1 正则化的线性回归模型。在特征选择中,Lasso 回归可以通过惩罚较小的系数并将一些系数缩减至零来实现特征筛选。其原理如下:
-
L1 正则化:Lasso 回归利用 L1 正则化项,该项对系数的绝对值进行惩罚。通过最小化损失函数和正则化项之和来训练模型,L1 正则化会导致一些系数变为零。
-
系数的重要性:在训练完成后,系数的绝对值大小可以表示特征的重要性。较大的系数对应的特征对目标变量的影响较大,较小的甚至为零的系数对应的特征则被认为不重要或者被模型忽略。
-
特征选择:通过设定一个阈值,比如这里的 0,可以根据系数的大小来筛选特征。系数绝对值大于阈值的特征被认为是重要的特征,进而被选中保留。
嵌入法,特别是基于 Lasso 回归的特征选择,适用于那些需要稀疏模型并且对解释性要求较高的情况。通过舍弃对目标变量影响较小的特征,可以简化模型并提高其解释性。
嵌入法:随机森林原理:
model = RandomForestClassifier()
model.fit(X_train, y_train)
importances = model.feature_importances_ # 得到每个特征对于标签的重要性
indices = np.argsort(importances)[::-1] # 特征重要性进行升序
print("Feature ranking:")
for f in range(X_train.shape[1]):
print("%d. feature %s (%f)" % (f + 1, X_train.columns[indices[f]], importances[indices[f]]))
-
RandomForestClassifier()
是 sklearn.ensemble 模块中的随机森林分类器,它由多个决策树组成,用来处理分类问题。 -
model.fit(X_train, y_train)
对训练集X_train
和对应的目标变量y_train
进行随机森林分类器的训练。 -
importances = model.feature_importances_
获取了每个特征对于目标变量(标签)的重要性,这是随机森林模型提供的一个属性。 -
indices = np.argsort(importances)[::-1]
对特征重要性进行降序排序,并返回排序后的索引。 -
print("Feature ranking:")
打印输出特征重要性的排名信息。 -
for f in range(X_train.shape[1]):
遍历所有特征,输出每个特征的排名和对应的重要性值。 -
print("%d. feature %s (%f)" % (f + 1, X_train.columns[indices[f]], importances[indices[f]]))
格式化输出每个特征的排名、特征名称和其重要性值。
结果图:
随机森林是一种集成学习算法,它由多棵决策树组成。在特征选择方面,随机森林通过以下方式评估每个特征的重要性:
-
Bagging:随机森林使用自助采样技术(bootstrap sampling)来随机选择训练集的子集,然后针对每个子集训练一棵决策树。
-
随机特征选择:在每棵决策树的训练过程中,随机森林从所有特征中随机选择一部分特征进行节点的分裂。这样做的目的是增加每棵树的差异性,从而提高整体模型的泛化能力。
-
特征重要性:对于随机森林模型,每个特征的重要性可以通过计算在所有树中每个特征被用来分裂节点的次数或者减少不纯度(比如基尼系数或信息增益)的程度来衡量。
-
平均重要性:最终,通过平均每个特征在所有决策树中的重要性得分来评估每个特征对于模型的整体贡献。
随机森林的特征重要性评估可以帮助理解每个特征对于预测目标的相对影响大小,从而在特征选择过程中帮助决定哪些特征是最关键的。这种方法对于处理高维数据和复杂数据模式非常有效。