在机器学习领域,特征选择和特征聚合是两种常用的降维技术。特征选择通过保留最重要的特征来减少数据集的维度,而特征聚合则是将多个特征合并成一个,以发现数据中的潜在结构。本文将介绍两种方法:单变量特征选择(使用Anova)和特征聚合(使用Ward层次聚类),并比较它们在贝叶斯岭回归问题中的表现。
实验中,首先生成了一组模拟数据,数据集包含200个样本,每个样本的大小为40x40像素。使用高斯滤波对数据进行平滑处理,并添加了一定比例的噪声。然后,使用贝叶斯岭回归模型作为监督估计器,来评估特征选择和特征聚合的效果。
单变量特征选择方法基于方差分析(Anova),它选择与目标变量相关性最强的特征。在本实验中,使用了一个名为f_regression的函数来计算每个特征的F值,然后使用SelectPercentile类来选择一定百分比的最重要的特征。通过网格搜索(GridSearchCV),找到了最优的特征百分比。
from sklearn.feature_selection import SelectPercentile, f_regression
# 缓存f_regression函数以加速计算
f_regression_cached = mem.cache(f_regression)
# 创建单变量特征选择器
anova = SelectPercentile(f_regression_cached)
# 创建包含特征选择和贝叶斯岭回归的管道
clf_anova = Pipeline([('anova', anova), ('ridge', ridge)])
# 使用网格搜索找到最优的特征百分比
clf_anova = GridSearchCV(clf_anova, {'anova__percentile': [5, 10, 20]}, cv=cv)
clf_anova.fit(X, y)
特征聚合方法使用Ward层次聚类将相邻的特征合并成一个。这种方法特别适合处理图像数据,因为它可以发现图像中的局部结构。在本实验中,使用grid_to_graph函数来创建图像的连接性矩阵,然后使用FeatureAgglomeration类来进行特征聚合。同样地,使用网格搜索来找到最优的聚合簇数。
from sklearn.cluster import FeatureAgglomeration
from sklearn.feature_extraction.image import grid_to_graph
# 创建图像的连接性矩阵
connectivity = grid_to_graph(n_x=size, n_y=size)
# 创建特征聚合器
ward = FeatureAgglomeration(n_clusters=10, connectivity=connectivity, memory=mem)
# 创建包含特征聚合和贝叶斯岭回归的管道
clf_ward = Pipeline([('ward', ward), ('ridge', ridge)])
# 使用网格搜索找到最优的聚合簇数
clf_ward = GridSearchCV(clf_ward, {'ward__n_clusters': [10, 20, 30]}, n_jobs=1, cv=cv)
clf_ward.fit(X, y)
为了比较两种方法的效果,将使用matplotlib库来可视化真实权重、特征选择后的权重和特征聚合后的权重。这将帮助直观地理解特征选择和特征聚合对数据的影响。
import matplotlib.pyplot as plt
# 关闭所有之前的图形
plt.close("all")
# 创建一个新的图形
plt.figure(figsize=(7.3, 2.7))
# 显示真实权重
plt.subplot(1, 3, 1)
plt.imshow(coef, interpolation="nearest", cmap=plt.cm.RdBu_r)
plt.title("真实权重")
# 显示特征选择后的权重
plt.subplot(1, 3, 2)
plt.imshow(coef_selection_, interpolation="nearest", cmap=plt.cm.RdBu_r)
plt.title("特征选择")
# 显示特征聚合后的权重
plt.subplot(1, 3, 3)
plt.imshow(coef_agglomeration_, interpolation="nearest", cmap=plt.cm.RdBu_r)
plt.title("特征聚合")
# 调整子图间距
plt.subplots_adjust(0.04, 0.0, 0.98, 0.94, 0.16, 0.26)
# 显示图形
plt.show()
在实验结束后,尝试删除临时缓存目录,以释放磁盘空间。如果删除失败,也不会影响实验结果。
import shutil
# 尝试删除临时缓存目录
shutil.rmtree(cachedir, ignore_errors=True)