目录
11.1子集收集与评价
属性称为"特征" ,对当前学习任务有用的属性称为"相关特征" 、没什么用的属性称为"无关特 征" . 从给定的特征集合中选择出相关特征于集的过程,称为"特征选择"。
特征选择是一个重要的"数据预处理" 过程。我们要从初始的特征集合中选取一个包含了所有重要信息的特征子集,首先,是子集搜索,给走特征集合 {a1,a2 ,... ad} ,我们可将每个特征看作一个候选子集,对这d个候选单特征子集进行评价,假定 {a2} 最优,于是将 {a2}作为第一轮的选定集;然后,在上一轮的选定集中加入一个特征,构成包含两个特征的候选子集,以此往复操作。其次,是子集评价,子集的信息增益为:
信息熵定义为:
信息增益 Gain(A) 越大,意味着特征子集 包含的有助于分类的信息越多.于是,对每个候选特征子集,我们可基于训练数据集来计算其信息增益,以此作为评价准则。
常见的特征选择方法大致可分为三类:过滤式 、包裹式 和嵌入式.
11.2过滤式选择
过滤式方法先对数据集进行特征选择,然后再训练学习器。
Relief 是一种著名的过滤式特征选择方法,该方法设计了一个"相关统计量"来度量特征的重要性。该统计量是一个向量,其每个分量分别对应于一个初始特征,而特征子集的重要性则是由子集中每个特征所对应的相关统计量分量之和来决定。
下面是关于Relief算法的过滤式特征选择方法的实验代码及分析和结果:
python
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.ensemble import RandomForestClassifier
from skfeature.function.statistical import reliefF
# 加载数据集
data = load_iris()
X = data.data
y = data.target
# 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 计算特征的ReliefF评分
reliefF_scores = reliefF.reliefF(X_train, y_train)
# 将特征按ReliefF评分排序
ranked_features = np.argsort(reliefF_scores)[::-1]
# 选择前k个特征
k = 2
selected_features = ranked_features[:k]
# 用选定的特征训练分类器
X_train_selected = X_train[:, selected_features]
X_test_selected = X_test[:, selected_features]
classifier = RandomForestClassifier(n_estimators=100, random_state=42)
classifier.fit(X_train_selected, y_train)
# 在测试集上评估分类器
y_pred = classifier.predict(X_test_selected)
accuracy = accuracy_score(y_test, y_pred)
print("Selected features:", selected_features)
print("Accuracy with selected features:", accuracy)
分析:
- ReliefF评分:该方法为每个特征计算一个重要性分数,反映了该特征对分类结果的影响。高分特征更为重要。
- 特征选择:根据ReliefF评分,选择排名前k的特征。这里选择了前2个特征。
- 分类性能:使用选定的特征训练随机森林分类器,并在测试集上评估准确性。最终的分类准确性显示了所选特征的有效性。
结果:
11.3包裹式选择
包裹式特征选择直接把最终将要使用的学习器的性能作为特征于集的评价准则.从最终学习器性能来看,包裹式特征选择比过滤式特征选择更好,但另一方面,由于在特征选择过程中需多次训练学习器,因此包裹式特征选择的计算开销通常比过滤式特征边择大得多.
LVW 是一个典型的包裹式特征选择方法,算法描述如下:
下面是关于LVW算法的实验代码及分析和结果:
python
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
# LVW 算法的伪实现
def lvw_algorithm(X_train, y_train, X_test, alpha=0.5):
"""
LVW算法的伪实现:假设权重为特征的均值
"""
feature_means = np.mean(X_train, axis=0)
weights = np.exp(alpha * feature_means) # 伪权重计算
X_train_weighted = X_train * weights
X_test_weighted = X_test * weights
# 用加权特征训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train_weighted, y_train)
return model, X_test_weighted
# 1. 数据加载
data = load_iris()
X = data.data
y = data.target
# 2. 数据预处理
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 3. 数据划分
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
# 4. 应用 LVW 算法
model, X_test_weighted = lvw_algorithm(X_train, y_train, X_test, alpha=0.5)
# 5. 预测与评估
y_pred = model.predict(X_test_weighted)
accuracy = accuracy_score(y_test, y_pred)
print(f"Model accuracy with LVW algorithm: {accuracy:.2f}")
分析:
-
数据集:我们使用了Iris数据集,这是一个多分类数据集,包含150个样本和4个特征。数据集已经标准化,以便于比较。
-
LVW算法实现:在这个伪实现中,LVW算法假设特征的均值用于计算权重。具体来说,我们将每个特征的均值取指数作为权重,并对训练数据和测试数据进行加权。这是一种简单的加权方法,实际的LVW算法可能会复杂得多。
-
模型训练与评估:我们使用加权后的训练数据训练逻辑回归模型,并在加权后的测试数据上进行预测。最后,计算模型的准确性。
结果:
11.4嵌入式选择与L1正则化
嵌入式特征选择是将特征选择过程与学习器训练过程融为一体。
给定数据集,最简单的线性回归模型,以平方误差为损失函数,则优化目标为:。
当样本特征很多,而样本数相对较少时,很容易陷入过拟合.为了缓解过拟合问题,引入正则化项:
L1范数和 L2 范数正则化都有助于降低过拟合风险,但前者还会带来一个额外的好处:它比后者更易于获得"稀疏" 解,即它求得的 会有更少的非零分量.
L1正则化问题的求 可使用近端梯度下降法(PGD)
下面是关于近端梯度下降法(PGD)算法解决L1正则化问题的实验代码及分析和结果:
python
import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso
from sklearn.metrics import mean_squared_error
def projected_gradient_descent(X, y, lambda_reg, alpha=0.01, num_iters=1000):
m, n = X.shape
theta = np.zeros(n)
for _ in range(num_iters):
gradient = -2 * X.T @ (y - X @ theta) / m
theta -= alpha * gradient
# Project onto L1 ball (soft thresholding)
theta = np.sign(theta) * np.maximum(0, np.abs(theta) - alpha * lambda_reg)
return theta
# 1. 数据生成
X, y = make_regression(n_samples=100, n_features=20, noise=0.1, random_state=42)
# 2. 设置参数
lambda_reg = 0.1 # L1正则化强度
alpha = 0.01 # 学习率
num_iters = 1000 # 迭代次数
# 3. 使用PGD算法求解
theta_pgd = projected_gradient_descent(X, y, lambda_reg, alpha, num_iters)
# 4. 用Lasso模型验证
lasso = Lasso(alpha=lambda_reg)
lasso.fit(X, y)
theta_lasso = lasso.coef_
# 5. 计算误差
mse_pgd = mean_squared_error(y, X @ theta_pgd)
mse_lasso = mean_squared_error(y, X @ theta_lasso)
print(f"PGD Mean Squared Error: {mse_pgd:.2f}")
print(f"Lasso Mean Squared Error: {mse_lasso:.2f}")
分析:
-
数据生成 :我们使用
make_regression
函数生成了一个回归数据集。数据集包含100个样本和20个特征,带有一定的噪声。 -
PGD算法实现 :在
projected_gradient_descent
函数中,我们通过梯度下降法更新参数,并在每次迭代后对参数进行L1范数的软阈值投影。这个过程确保参数的L1范数约束被满足,即实施了L1正则化。 -
Lasso模型验证 :为了验证PGD算法的结果,我们还使用了Scikit-learn的
Lasso
模型,它本质上使用了相同的L1正则化技术。 -
误差计算:我们计算了PGD算法和Lasso模型的均方误差(MSE),以比较它们在数据上的表现。
结果:
11.5稀疏表示与字典学习
将样品稀疏表示,可以使学习任务的难度可能有所降低?涉及的计算和存储开销会减少, 学得模型的可解释性也会提高。字典学习 亦称"稀疏编码"。是为普通稠密表达的样本找到合适的字典,将样本转化为合适的稀疏表示形式,从而使学习任务得以简化。
给定数据集,字典学习最简单的形式为:
其中 为字典矩阵 ,k 称为字典的词汇量,通常由用户指定, 是样本 的稀疏表示.
11.6压缩感知
在现实任务中,我们常希望根据部分信息来恢复全部信息。通常选择压缩的方法。压缩感知为精确地重构出原信号提供了方法。
在很多应用中均可获得具有稀疏性的 例如图像或声音的数字信 号通常在时域上不具有稀疏性,但经过傅里叶变换、余弦变换、小波变换等处 理后却会转化为频域上的稀疏信号.与特征选择、稀疏表示不同,压缩感知关注的是如何利用信号本身所具有的稀疏性,从部分观测样本中恢复原信号。
限定等距性( RIP)是一种用于描述稀疏信号恢复算法中矩阵性质的概念。它主要用于压缩感知(Compressed Sensing)和信号处理领域,用来确保一个矩阵能够以接近原始信号的方式保留稀疏信号的几何结构。
给定一个的矩阵和一个正整数,我们称 满足 (s, δ)限定等距性,如果对于所有的 稀疏向量 x(即只有 s个非零元素的向量),矩阵 满足以下条件:
其中:
表示向量x 的二范数(Euclidean norm)。
是一个正的常数,称为(s, δ)等距性常数,它衡量了矩阵 保持 s-稀疏向量的几何结构的能力。
-
稀疏恢复:RIP 是压缩感知理论中的一个关键性质,保证了使用特定矩阵(如随机矩阵或测量矩阵)时,稀疏信号可以从其线性测量中有效恢复。这意味着,即使我们仅从少量的测量中得到信息,也能准确地重建原始信号。
-
优化算法的理论保证:RIP 为压缩感知中的许多优化算法提供理论保证,说明这些算法可以在有限的测量数量下恢复稀疏信号。