当前位置: 首页 > news >正文

机器学习第十一章-特征选择与稀疏学习

11.1子集收集与评价

        属性称为"特征" ,对当前学习任务有用的属性称为"相关特征" 、没什么用的属性称为"无关特 征" . 从给定的特征集合中选择出相关特征于集的过程,称为"特征选择"。

        特征选择是一个重要的"数据预处理" 过程。我们要从初始的特征集合中选取一个包含了所有重要信息的特征子集,首先,是子集搜索,给走特征集合 {a1,a2 ,... ad} ,我们可将每个特征看作一个候选子集,对这d个候选单特征子集进行评价,假定 {a2} 最优,于是将 {a2}作为第一轮的选定集;然后,在上一轮的选定集中加入一个特征,构成包含两个特征的候选子集,以此往复操作。其次,是子集评价,子集的信息增益为:\operatorname{Gain}(A)=\operatorname{Ent}(D)-\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \operatorname{Ent}\left(D^{v}\right)

                                 信息熵定义为:\operatorname{Ent}(D)=-\sum_{i=1}^{|\mathcal{Y}|} p_{k} \log _{2} p_{k}

        信息增益 Gain(A) 越大,意味着特征子集 包含的有助于分类的信息越多.于是,对每个候选特征子集,我们可基于训练数据集来计算其信息增益,以此作为评价准则。
        常见的特征选择方法大致可分为三类:过滤式 、包裹式 和嵌入式.

11.2过滤式选择

        过滤式方法先对数据集进行特征选择,然后再训练学习器。

        Relief 是一种著名的过滤式特征选择方法,该方法设计了一个"相关统计量"来度量特征的重要性。该统计量是一个向量,其每个分量分别对应于一个初始特征,而特征子集的重要性则是由子集中每个特征所对应的相关统计量分量之和来决定。

下面是关于Relief算法的过滤式特征选择方法的实验代码及分析和结果:

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)

分析:

  1. ReliefF评分:该方法为每个特征计算一个重要性分数,反映了该特征对分类结果的影响。高分特征更为重要。
  2. 特征选择:根据ReliefF评分,选择排名前k的特征。这里选择了前2个特征。
  3. 分类性能:使用选定的特征训练随机森林分类器,并在测试集上评估准确性。最终的分类准确性显示了所选特征的有效性。

结果:

11.3包裹式选择

        包裹式特征选择直接把最终将要使用的学习器的性能作为特征于集的评价准则.从最终学习器性能来看,包裹式特征选择比过滤式特征选择更好,但另一方面,由于在特征选择过程中需多次训练学习器,因此包裹式特征选择的计算开销通常比过滤式特征边择大得多.
        LVW 是一个典型的包裹式特征选择方法,算法描述如下:
下面是关于LVW算法的实验代码及分析和结果:
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 * weightsX_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}")

分析:

  1. 数据集:我们使用了Iris数据集,这是一个多分类数据集,包含150个样本和4个特征。数据集已经标准化,以便于比较。

  2. LVW算法实现:在这个伪实现中,LVW算法假设特征的均值用于计算权重。具体来说,我们将每个特征的均值取指数作为权重,并对训练数据和测试数据进行加权。这是一种简单的加权方法,实际的LVW算法可能会复杂得多。

  3. 模型训练与评估:我们使用加权后的训练数据训练逻辑回归模型,并在加权后的测试数据上进行预测。最后,计算模型的准确性。

结果:

11.4嵌入式选择与L1正则化

        嵌入式特征选择是将特征选择过程与学习器训练过程融为一体。

        给定数据集D=\left\{\left(\boldsymbol{x}_{1}, y_{1}\right),\left(\boldsymbol{x}_{2}, y_{2}\right), \ldots,\left(\boldsymbol{x}_{m}, y_{m}\right)\right\},最简单的线性回归模型,以平方误差为损失函数,则优化目标为:\min _{\boldsymbol{w}} \sum_{i=1}^{m}\left(y_{i}-\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}_{i}\right)^{2}

        当样本特征很多,而样本数相对较少时,很容易陷入过拟合.为了缓解过拟合问题,引入正则化项:\min _{\boldsymbol{w}} \sum_{i=1}^{m}\left(y_{i}-\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}_{i}\right)^{2}+\lambda\|\boldsymbol{w}\|_{2}^{2}
        L1范数和 L2 范数正则化都有助于降低过拟合风险,但前者还会带来一个额外的好处:它比后者更易于获得"稀疏" 解,即它求得的 会有更少的非零分量.

        L1正则化问题的求 可使用近端梯度下降法(PGD)

下面是关于近端梯度下降法(PGD)算法解决L1正则化问题的实验代码及分析和结果:

import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso
from sklearn.metrics import mean_squared_errordef projected_gradient_descent(X, y, lambda_reg, alpha=0.01, num_iters=1000):m, n = X.shapetheta = np.zeros(n)for _ in range(num_iters):gradient = -2 * X.T @ (y - X @ theta) / mtheta -= 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}")

分析:

  1. 数据生成:我们使用make_regression函数生成了一个回归数据集。数据集包含100个样本和20个特征,带有一定的噪声。

  2. PGD算法实现:在projected_gradient_descent函数中,我们通过梯度下降法更新参数,并在每次迭代后对参数进行L1范数的软阈值投影。这个过程确保参数的L1范数约束被满足,即实施了L1正则化。

  3. Lasso模型验证:为了验证PGD算法的结果,我们还使用了Scikit-learn的Lasso模型,它本质上使用了相同的L1正则化技术。

  4. 误差计算:我们计算了PGD算法和Lasso模型的均方误差(MSE),以比较它们在数据上的表现。

结果:

11.5稀疏表示与字典学习

        将样品稀疏表示,可以使学习任务的难度可能有所降低?涉及的计算和存储开销会减少, 学得模型的可解释性也会提高。字典学习 亦称"稀疏编码"。是为普通稠密表达的样本找到合适的字典,将样本转化为合适的稀疏表示形式,从而使学习任务得以简化。

        给定数据集\left\{\boldsymbol{x}_{1}, \boldsymbol{x}_{2}, \ldots, \boldsymbol{x}_{m}\right\},字典学习最简单的形式为:

                                        ​​​​​​​        \min _{\mathbf{B}, \boldsymbol{\alpha}_{i}} \sum_{i=1}^{m}\left\|\boldsymbol{x}_{i}-\mathbf{B} \boldsymbol{\alpha}_{i}\right\|_{2}^{2}+\lambda \sum_{i=1}^{m}\left\|\boldsymbol{\alpha}_{i}\right\|_{1}

其中 \mathbf{B} \in \mathbb{R}^{d \times k} 为字典矩阵 ,k 称为字典的词汇量,通常由用户指定,\alpha _{i} \in \mathbb{R}^{k} 是样本x_{i} \in \mathbb{R}^{d}  的稀疏表示.

       

11.6压缩感知

        在现实任务中,我们常希望根据部分信息来恢复全部信息。通常选择压缩的方法。压缩感知为精确地重构出原信号提供了方法。

        在很多应用中均可获得具有稀疏性的 例如图像或声音的数字信 号通常在时域上不具有稀疏性,但经过傅里叶变换、余弦变换、小波变换等处 理后却会转化为频域上的稀疏信号.与特征选择、稀疏表示不同,压缩感知关注的是如何利用信号本身所具有的稀疏性,从部分观测样本中恢复原信号。

        限定等距性( RIP)是一种用于描述稀疏信号恢复算法中矩阵性质的概念。它主要用于压缩感知(Compressed Sensing)和信号处理领域,用来确保一个矩阵能够以接近原始信号的方式保留稀疏信号的几何结构。

        给定一个m \times n的矩阵\Phi和一个正整数s,我们称 \Phi满足 (s, δ)限定等距性,如果对于所有的 s -稀疏向量 x(即只有 s个非零元素的向量),矩阵 \Phi满足以下条件:

(1 - \delta_s) \|x\|_2^2 \leq \|\Phi x\|_2^2 \leq (1 + \delta_s) \|x\|_2^2

其中:
- \|x\|_2表示向量x 的二范数(Euclidean norm)。
\delta_s是一个正的常数,称为(s, δ)等距性常数,它衡量了矩阵 \Phi保持 s-稀疏向量的几何结构的能力。

1. 稀疏恢复:RIP 是压缩感知理论中的一个关键性质,保证了使用特定矩阵(如随机矩阵或测量矩阵)时,稀疏信号可以从其线性测量中有效恢复。这意味着,即使我们仅从少量的测量中得到信息,也能准确地重建原始信号。

2. 优化算法的理论保证:RIP 为压缩感知中的许多优化算法提供理论保证,说明这些算法可以在有限的测量数量下恢复稀疏信号。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Vue3.0生命周期钩子(包含:Vue 2.0 和 Vue 3.0)
  • JavaEE 的相关知识点(一)
  • [000-002-01].数据库调优相关学习
  • python提取b站视频的音频(提供源码
  • 华为---端口隔离简介和示例配置
  • 牛客周赛 Round 56
  • 索引——appinventor
  • Spring Boot 实现定时任务
  • mysql实现分布式锁
  • 力学笃行(五)Qt key绑定、钩子(hook)
  • H5漂流瓶交友源码_社交漂流瓶H5源码
  • csrf漏洞(二)
  • GNS3 IOU: License section not found in iourc file /tmp/tmpj54abrhf/iourc
  • day01-作业题
  • 深度学习入门(E):逻辑回归与分类到底是啥关系?
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • Asm.js的简单介绍
  • ES6系列(二)变量的解构赋值
  • java 多线程基础, 我觉得还是有必要看看的
  • linux安装openssl、swoole等扩展的具体步骤
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Service Worker
  • Zsh 开发指南(第十四篇 文件读写)
  • 给初学者:JavaScript 中数组操作注意点
  • 构建工具 - 收藏集 - 掘金
  • 聊一聊前端的监控
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 算法---两个栈实现一个队列
  • 为视图添加丝滑的水波纹
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​Redis 实现计数器和限速器的
  • ​第20课 在Android Native开发中加入新的C++类
  • ‌‌雅诗兰黛、‌‌兰蔻等美妆大品牌的营销策略是什么?
  • # .NET Framework中使用命名管道进行进程间通信
  • $.ajax中的eval及dataType
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (2)Java 简介
  • (超详细)语音信号处理之特征提取
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (回溯) LeetCode 40. 组合总和II
  • (七)glDrawArry绘制
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)为C# Windows服务添加安装程序
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .bat批处理(一):@echo off
  • .NET CORE 第一节 创建基本的 asp.net core
  • .Net FrameWork总结
  • .NET 反射 Reflect
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...