多元特征过滤(Multivariate Filter Methods)
单变量特征过滤仅考虑了每一变量与目标变量之间的关系,而忽视了变量间的相关性。多元变量过滤则解决了这一问题,其考虑了变量之间的相互关系,基于整个特征空间选择最佳特征。因此多元特征过滤在删除冗余变量方面表现更好。这里用到了除了sklearn以外的一个新的库skfeature
最大相关最小冗余
最大相关最小冗余(Max-Relevance Min-Redundancy 简称:mRMR)试图寻找一个与目标变量有较高相关性(例如:互信息)的变量子集,同时这个子集中的变量还应具有较低的相互关联性。skfeature中最大相关最小冗余方法仅适用于分类问题中的离散特征,因为它计算过程中使用的是计算离散情形下的互信息 (MI)的公式。
import numpy as np
from skfeature.function.information_theoretical_based import MRMR
from sklearn.datasets import load_iris # 利用iris数据作为演示数据集
# 载入数据集
iris = load_iris()
X, y = iris.data, iris.target
# 选择前100个观测点作为训练集
# 剩下的50个观测点作为测试集
# 由于skfeature中的mRMR仅适用于离散变量
# 因此我们通过将float转换为int而把所有连续变量转换为离散变量
# 此转换仅用于演示目的
train_set = X[0:100,:].astype(int)
test_set = X[100:,].astype(int)
train_y = y[0:100].astype(int)
feature_index,_,_ = MRMR.mrmr(train_set, train_y, n_selected_features=2) # 在训练集上训练
transformed_train = train_set[:,feature_index] # 转换训练集
assert np.array_equal(transformed_train, train_set[:,[2,3]]) # 其选择了第三个及第四个变量
transformed_test = test_set[:,feature_index] # 转换测试集
assert np.array_equal(transformed_test, test_set[:,[2,3]]) # 其选择了第三个及第四个变量
基于相关性的特征选择
与mRMR类似,基于相关性的特征选择(Correlation-based Feature Selection 简称:CFS)也基于一个类似的假设:一个好的特征子集应包含与目标高度相关且彼此不相关的特征。skfeature中CFS的实现也仅适用于分类问题中的离散特征。因为其使用的是离散情形下的对称不确定性(symmetrical uncertainty)作为变量间相关性的衡量标准。
import numpy as np
from skfeature.function.statistical_based import CFS
from sklearn.datasets import load_iris # 利用iris数据作为演示数据集
# 载入数据集
iris = load_iris()
X, y = iris.data, iris.target
# 选择前100个观测点作为训练集
# 剩下的50个观测点作为测试集
# 由于skfeature中的CFS仅适用于离散变量
# 因此我们通过将float转换为int而把所有连续变量转换为离散变量
# 此转换仅用于演示目的
train_set = X[0:100,:].astype(int)
test_set = X[100:,].astype(int)
train_y = y[0:100].astype(int)
num_feature = 2 # 从原数据集中选择两个变量
feature_index = CFS.cfs(train_set, train_y) # 在训练集上训练
transformed_train = train_set[:,feature_index[0:num_feature]] # 转换训练集
assert np.array_equal(transformed_train, train_set[:,[3,2]]) # 其选择了第三个及第四个变量
transformed_test = test_set[:,feature_index[0:num_feature]] # 转换测试集
assert np.array_equal(transformed_test, test_set[:,[3,2]]) # 其选择了第三个及第四个变量
基于相关性的快速特征选择
基于相关性的快速特征选择(Fast Correlation-based Filter 简称:FCBS)相比于CFS,FCBS能够更加高效的筛选变量。其同样为逐步(step-wise)的方法,具体步骤与mRMR非常类似,但FCBS使用对称不确定性(SU)衡量变量间的关联性。FCBF首先剔除与目标变量具有较低SU值的变量,并对剩下的变量按与目标变量的SU值从最高到最低排序,然后逐一删除冗余特征。与mRMR,CFS相似,在skfeature中实现的FCBF仅适用于具有离散变量的分类问题。
import numpy as np
from skfeature.function.information_theoretical_based import FCBF
from sklearn.datasets import load_iris # 利用iris数据作为演示数据集
# 载入数据集
iris = load_iris()
X, y = iris.data, iris.target
# 选择前100个观测点作为训练集
# 剩下的50个观测点作为测试集
# 由于skfeature中的FCFS仅适用于离散变量
# 因此我们通过将float转换为int而把所有连续变量转换为离散变量
# 此转换仅用于演示目的
train_set = X[0:100,:].astype(int)
test_set = X[100:,].astype(int)
train_y = y[0:100].astype(int)
num_feature = 2 # 从原数据集中选择两个变量
feature_index = FCBF.fcbf(train_set, train_y, n_selected_features = num_feature)[0] # 在训练集上训练
transformed_train = train_set[:,feature_index[0:num_feature]] # 转换训练集
assert np.array_equal(transformed_train, train_set[:,[3]]) # 其仅选择了第四个变量
# 这是由于其他变量目标变量 之间的相关性过低造成的
transformed_test = test_set[:,feature_index[0:num_feature]] # 转换测试集
assert np.array_equal(transformed_test, test_set[:,[3]]) # 其仅选择了第四个变量
ReliefF
ReliefF方法是一种基于Relief方法的特征加权算法。在Relief方法中,其根据特征与目标变量的相关性强弱(二分类)给变量分配权重,并删除权重低于特定阈值的特征。其将相关性定义为变量区分邻近观测点的能力。
具体来说,在每一步中,Relief方法都会从训练集中随机选择一个观测点S,然后找到具有相同目标标签的S的最近邻观测点,称为NearHit。它还将找到具有不同目标标签的S的最近邻观测点,称为NearMiss。然后根据以下规则更新每个功能的权重:
- 若观测点S在某变量上与NearHit的距离大于与NearMiss的距离,则该变量的权重将增加,因为变量有助于区分最邻近情形下的目标标签。
- 相反,若观测点S在某变量上与NearHit的距离小于与NearMiss的距离,则该变量的权重会降低。
将上述过程重复m次,最后我们会获得每个特征变量的平均权重。特征变量的权重越大,则特征的分类能力越强,越应该被留在最终的特征子集中。
在ReliefF中,其修改了权重更新的方式,因此ReliefF方法可以被应用于多类分类问题。另外,它随机采样K个最近的观测点而不是一个。
在skfeature中实现的ReliefF可用于分类问题中的连续特征或二元类别特征,因其使用的是L1范数来衡量差异。针对非二元特征,我们可以先将其独热编码,再使用ReliefF方法。
import numpy as np
from skfeature.function.similarity_based import reliefF
from sklearn.datasets import load_iris # 利用iris数据作为演示数据集
# 载入数据集
iris = load_iris()
X, y = iris.data, iris.target
# 选择前100个观测点作为训练集
# 剩下的50个观测点作为测试集
# skfeature中的reliefF直接适用于连续变量
train_set = X[0:100,:]
test_set = X[100:,]
train_y = y[0:100]
num_feature = 2 # 从原数据集中选择两个变量
score = reliefF.reliefF(train_set, train_y) # 计算每一个变量的权重
feature_index = reliefF.feature_ranking(score) # 依据权重选择变量
transformed_train = train_set[:,feature_index[0:num_feature]] # 转换训练集
assert np.array_equal(transformed_train, train_set[:,[2, 3]]) # 其选择了第三个及第四个变量
transformed_test = test_set[:,feature_index[0:num_feature]] # 转换测试集
assert np.array_equal(transformed_test, test_set[:,[2, 3]]) # 其选择了第三个及第四个变量
基于谱图的特征选择
基于谱图的特征选择(Spectral Feature Selectio 简称:SPEC)方法是基于谱图理论的无监督方法。其首先建立变量相似度集合S,并建立其图表示。然后,其根据构造图的频谱评估特征。由于在skfeature中实现的SPEC方基于RBF(高斯)内核建立相似集,因此其可用于分类问题中的连续特征或二元类别特征。针对非二元特征,我们可以先将其独热编码,再使用ReliefF方法。
import numpy as np
from skfeature.function.similarity_based import SPEC
from sklearn.datasets import load_iris # 利用iris数据作为演示数据集
# 载入数据集
iris = load_iris()
X, y = iris.data, iris.target
# 选择前100个观测点作为训练集
# 剩下的50个观测点作为测试集
# skfeature中的SEPC方法直接适用于连续变量
train_set = X[0:100,:]
test_set = X[100:,]
train_y = y[0:100]
num_feature = 2 # 从原数据集中选择两个变量
score = SPEC.spec(train_set) # 计算每一个变量的得分
feature_index = SPEC.feature_ranking(score) #依据变量得分选择变量
transformed_train = train_set[:,feature_index[0:num_feature]] # 转换训练集
assert np.array_equal(transformed_train, train_set[:,[1, 0]]) # 其选择了第一个及第二个变量
transformed_test = test_set[:,feature_index[0:num_feature]] # 转换测试集
assert np.array_equal(transformed_test, test_set[:,[1, 0]]) # 其选择了第一个及第二个变量