signal-opt

导航

稀疏贝叶斯学习

稀疏贝叶斯学习(SBL)是一种将稀疏性和贝叶斯统计相结合的学习方法,主要应用于信号处理、机器学习中的稀疏表示、特征选择等。

本质在于通过贝叶斯推理来估计模型参数,使得得到的解既具有稀疏性又能够较好地解释观测数据。相比于传统的稀疏方法(如 \(l_1\) 正则化),SBL不需要预先指定稀疏度参数,而是通过学习自适应地发现稀疏结构。

本文主要探讨稀疏贝叶斯学习的相关内容

1.理论基础

稀疏贝叶斯学习的理论基础主要包括贝叶斯统计稀疏表示。其核心是通过给模型参数设置合适的先验分布,并基于观测数据进行后验更新,从而找到稀疏解。

1.1贝叶斯统计

image

对于两个随机变量 \(\theta\)\(X\),它们的联合概率 \(p(\theta, X)\) 表示 \(\theta\)\(X\) 同时发生的概率。联合概率可以用条件概率的定义来表示:

\[p(\theta, X) = p(X | \theta) p(\theta) \]

这表示在先验情况下发生 \(\theta\) 的概率为 \(p(\theta)\),在 \(\theta\) 发生后,\(X\) 的条件概率为 \(p(X|\theta)\),二者的乘积给出了联合概率 \(p(\theta, X)\)

同理,也可以表示为:

\[p(\theta, X) = p(\theta | X) p(X) \]

这表示我们先观测到 \(X\) 的发生,得到 \(p(X)\),然后在 \(X\) 发生的情况下发生 \(\theta\) 的条件概率 \(p(\theta|X)\),二者的乘积也给出了联合概率 \(p(\theta, X)\)

从上面的两个表示方式中,得到如下等式:

\[p(X | \theta) p(\theta) = p(\theta | X) p(X) \]

因为二者都表示 \(\theta\)\(X\) 同时发生的联合概率。将这个等式改写后,可以得到后验概率 \(p(\theta | X)\) 的表达式:

\[p(\theta | X) = \frac{p(X | \theta) p(\theta)}{p(X)} \]

  • \(p(\theta | X)\) 表示后验概率,即在观测数据 \(X\) 已知的情况下对参数 \(\theta\) 的信念更新。
  • \(p(X | \theta)\) 表示似然函数,即在给定参数 \(\theta\) 下数据 \(X\) 出现的可能性。
  • \(p(\theta)\) 是先验概率,即在观测数据 \(X\) 出现之前,对参数 \(\theta\) 的信念。
  • \(p(X)\) 是边缘似然(证据),用于归一化后验分布,使得后验分布的积分为 1。

边缘似然 \(p(X)\) 是所有可能的 \(\theta\) 值下,数据 \(X\) 的联合概率的积分或求和。可以通过对联合分布 \(p(X, \theta)\) 关于 \(\theta\) 积分得到:

\[p(X) = \int p(X | \theta) p(\theta) \, d\theta \]

边缘似然的作用是确保后验概率的归一化,使得所有可能的 \(\theta\) 的后验概率之和为 1

1.2稀疏表示

稀疏表示是一种数据建模方式,旨在通过稀疏的参数向量描述数据。稀疏表示在很多场景中是非常有效的,因为信号通常可以通过较少的特征或基来进行准确的重构。常见的稀疏表示方法包括 Lasso、\(l_0\) 正则化和 \(l_1\) 正则化。稀疏贝叶斯学习通过设置稀疏先验来诱导参数的稀疏性。

2.稀疏贝叶斯学习模型

SBL 的模型通常通过定义参数的稀疏先验分布和观测模型来构建。常用的稀疏贝叶斯模型包括稀疏贝叶斯回归和稀疏贝叶斯分类。下面我们以稀疏贝叶斯回归模型为例,简要介绍该模型的学习过程。

考虑一个线性回归模型:

\[y = Xw + \epsilon \]

其中:

  • \(y \in \mathbb{R}^N\) 表示观测数据;
  • \(X \in \mathbb{R}^{N \times M}\) 为设计矩阵;
  • \(w \in \mathbb{R}^M\) 为模型参数向量;
  • \(\epsilon \sim \mathcal{N}(0, \sigma^2 I)\) 为观测噪声。

目标是通过贝叶斯推理找到一个稀疏的 \(w\) 使得数据 \(y\) 得到最佳解释。

为了诱导稀疏性,我们对参数 \(w\) 设置一个稀疏的先验分布。常用的是零均值的高斯分布,并使用一个独立的精度参数 \(\alpha_i\) 来控制每个 \(w_i\) 的方差:

\[p(w | \alpha) = \mathcal{N}(w | 0, \text{diag}(\alpha^{-1})) \]

其中 \(\alpha = (\alpha_1, \alpha_2, \dots, \alpha_M)^T\) 是精度参数的向量,每个 \(\alpha_i\) 控制 \(w_i\) 的方差。当 \(\alpha_i\) 趋于无穷大时,\(w_i\) 的分布趋近于零,从而实现稀疏性。

假设观测数据的噪声为高斯分布,则观测数据的似然函数为:

\[p(y | w, \sigma^2) = \mathcal{N}(y | Xw, \sigma^2 I) = \frac{1}{(2 \pi \sigma^2)^{N/2}} \exp\left(-\frac{1}{2 \sigma^2} \|y - Xw\|^2\right) \]

其中,

  • $ X $ 是设计矩阵,表示数据与参数的关系;
  • $ N $ 是观测数据的维度。

基于贝叶斯定理,我们可以得到 \(w\) 的后验分布:

\[p(w | y, \alpha, \sigma^2) = \frac{p(y | w, \sigma^2) p(w | \alpha)}{p(y | \alpha, \sigma^2)} \]

其中 \(p(y | \alpha, \sigma^2)\) 是边缘似然或称为证据,用于归一化后验分布。

为了进行模型优化,需要最大化边缘似然 \(p(y | \alpha, \sigma^2)\)。边缘似然通过积分对 \(w\) 积分计算:

\[p(y | \alpha, \sigma^2) = \int p(y | w, \sigma^2) p(w | \alpha) dw \]

注意:参数 $ w $ 具有一个零均值的高斯先验分布,精度参数由向量 $\alpha $ 控制:

\[p(w | \alpha) = \mathcal{N}(w | 0, \text{diag}(\alpha^{-1})) = \frac{1}{(2 \pi)^{M/2} |\text{diag}(\alpha^{-1})|^{1/2}} \exp\left(-\frac{1}{2} w^T \text{diag}(\alpha) w\right) \]

其中:

  • $ M $ 是参数$ w $ 的维度;
  • $ \text{diag}(\alpha) $ 是一个对角矩阵,包含 $ \alpha $ 中的元素。

将上面的似然函数和先验分布代入边缘似然的公式:

\[p(y | \alpha, \sigma^2) = \int \frac{1}{(2 \pi \sigma^2)^{N/2}} \exp\left(-\frac{1}{2 \sigma^2} \|y - Xw\|^2\right) \cdot \frac{1}{(2 \pi)^{M/2} |\text{diag}(\alpha^{-1})|^{1/2}} \exp\left(-\frac{1}{2} w^T \text{diag}(\alpha) w\right) \, dw \]

将指数部分合并到一起:

\[p(y | \alpha, \sigma^2) = \frac{1}{(2 \pi \sigma^2)^{N/2} (2 \pi)^{M/2} |\text{diag}(\alpha^{-1})|^{1/2}} \int \exp\left(-\frac{1}{2} \left( \frac{1}{\sigma^2} \|y - Xw\|^2 + w^T \text{diag}(\alpha) w \right) \right) \, dw \]

再将指数中的项展开并化简为一个关于 $ w $ 的二次型。令:

\[\|y - Xw\|^2 = (y - Xw)^T (y - Xw) = y^T y - 2 y^T X w + w^T X^T X w \]

这样,指数项可以写为:

\[-\frac{1}{2} \left( \frac{1}{\sigma^2} (y^T y - 2 y^T X w + w^T X^T X w) + w^T \text{diag}(\alpha) w \right) \]

合并所有关于 $ w $ 的项,得到一个新的二次型形式:

\[-\frac{1}{2} \left( w^T \left( \frac{X^T X}{\sigma^2} + \text{diag}(\alpha) \right) w - 2 w^T \frac{X^T y}{\sigma^2} \right) \]

将二次型写成完全平方形式,定义:

\[\Sigma_w = \left( \frac{X^T X}{\sigma^2} + \text{diag}(\alpha) \right)^{-1}, \quad \mu_w = \Sigma_w \frac{X^T y}{\sigma^2} \]

则指数项可以写成:

\[-\frac{1}{2} \left( (w - \mu_w)^T \Sigma_w^{-1} (w - \mu_w) \right) - \frac{1}{2} \left( y^T y - \mu_w^T \Sigma_w^{-1} \mu_w \right) \]

由于积分只涉及 $ w $ 的项,因此 $ (w - \mu_w)^T \Sigma_w^{-1} (w - \mu_w) $ 的积分是一个高斯积分,结果为 1。所以边缘似然为:

\[p(y | \alpha, \sigma^2) = \frac{1}{(2 \pi)^{N/2} |\Sigma_y|^{1/2}} \exp\left(-\frac{1}{2} y^T \Sigma_y^{-1} y \right) \]

其中,$$ \Sigma_y = \sigma^2 I + X \text{diag}(\alpha^{-1}) X^T $$

2.1期望最大化算法

为了找到最佳的稀疏解,我们希望通过最大化边缘似然 $ p(y | \alpha, \sigma^2) $ 来估计精度参数 $ \alpha $ 和噪声方差 $ \sigma^2 $.

通常采用期望最大化(EM)算法来实现这一优化过程。EM 算法是一种迭代优化方法,适用于处理具有隐藏变量或不确定参数的问题。在稀疏贝叶斯学习中,其可以自适应地找到最稀疏的参数解.

image

(1). E 步骤:计算 $ w $ 的后验分布

在 E 步骤中,我们希望估计 $ w $ 的后验分布 $ p(w | y, \alpha, \sigma^2) $。假设已经有了当前的超参数 $ \alpha $ 和 $\sigma^2 $ 的值,那么可以计算出 $ w $ 的后验分布为一个高斯分布,其均值和协方差分别为:

\[\mu_w = \Sigma_w \frac{X^T y}{\sigma^2} \]

\[\Sigma_w = \left( \frac{X^T X}{\sigma^2} + \text{diag}(\alpha) \right)^{-1} \]

其中:

  • $ \mu_w $ 是后验分布的均值,表示在给定数据和当前超参数下,参数 ( w ) 的最可能值。
  • $ \Sigma_w $ 是后验分布的协方差矩阵,反映了 $ w $ 的不确定性。其对角元素 $ \Sigma_{w, ii} $ 代表了$ w_i $ 的方差。

这些后验分布参数用于指导 M 步骤中的超参数更新。

(2). M 步骤:更新超参数 $ \alpha $ 和 $ \sigma^2$

在 M 步骤中,利用 E 步骤计算得到的后验分布的均值和协方差,更新超参数 $\alpha $ 和 $ \sigma^2 $ 的值,使得边缘似然 $ p(y | \alpha, \sigma^2) $ 最大化。

更新精度参数$ \alpha $

对于每个 $ \alpha_i $,更新公式为:

\[\alpha_i^{\text{new}} = \frac{1 - \alpha_i \Sigma_{w, ii}}{w_i^2} \]

其中:

  • $ \Sigma_{w, ii} $ 是后验协方差矩阵 $ \Sigma_w $ 的第 $ i $ 个对角元素。
  • $ w_i $ 是后验分布均值 $ \mu_w $ 中第 $ i $ 个元素。

这个更新公式的推导基于最大化边缘似然的期望。更新公式反映了一个稀疏性诱导机制:当$ w_i$ 对数据的贡献较小时,协方差元素 \(\Sigma_{w, ii}\) 会相对较大,从而使得 $ \alpha_i $ 增大,进一步抑制 $ w_i $ 的重要性;反之,当 $w_i $ 对数据的贡献较大时,$ \alpha_i $会相对较小,使 $ w_i $ 得到保留。

更新噪声方差 \(\sigma^2\)

噪声方差 $ \sigma^2 $ 的更新公式为:

\[\sigma^2 = \frac{\| y - X \mu_w \|^2}{N - \sum_{i=1}^M (1 - \alpha_i \Sigma_{w, ii})} \]

其中:

  • $ | y - X \mu_w |^2$ 表示数据 $ y $ 与模型预测的误差平方和。
  • $ N $ 是数据样本数,$ M $ 是参数 $ w $ 的维度。

这个公式的分母中包含一项修正项 $\sum_{i=1}^M (1 - \alpha_i \Sigma_{w, ii}) $,该项是实际模型参数的有效自由度。它表示在数据拟合过程中,有效的自由参数数目随着稀疏性增加而减少,从而调整了噪声方差的估计值。这样,模型能够自适应地确定合适的噪声水平。

3.稀疏贝叶斯学习的稀疏性解释

实际上,在 SBL 中,稀疏性通过调节 \(\alpha\) 的值来实现。当 \(\alpha_i\) 很大时,对应的参数 \(w_i\) 的方差会很小,趋近于零;当 \(\alpha_i\) 很小(接近零)时,对应的 \(w_i\) 会有较大的方差。这种机制使得模型自动选择少量的重要特征,并抑制无用的特征,从而实现稀疏解。

4.实验

该实验的流程如下:首先,生成一个稀疏的高维设计矩阵和目标变量,其中目标变量包含少量非零特征系数并加入噪声。接着,对比了稀疏贝叶斯学习(SBL)和 Ridge 回归两种模型的表现,分别通过不同噪声水平下的均方误差(MSE)、平均绝对误差(MAE)、最大误差和解释方差(R²分数)等指标,评估它们的抗噪性和稀疏性表现。实验绘制了模型在不同噪声水平下的误差变化趋势,并通过稀疏度和范数对比进一步分析了两种模型的稀疏性.

image

从图中可以观察到,随着噪声水平的增加,均方误差 (MSE 和 均方根误差 (RMSE) 都呈现逐渐上升的趋势,显示出模型在高噪声条件下精度下降的现象。Ridge 和 SBL 两种模型的表现非常接近,尤其在低噪声水平下,误差指标几乎相同。这表明在处理稀疏信号的情况下,SBL 和 Ridge 模型在稳定性和抗噪能力方面具有相似的效果.

同时,在最大误差和解释方差的对比中,我们可以看到 Ridge 模型的解释方差在噪声增加时波动较大,而 SBL 相对稳定。这种差异可能表明 SBL 对噪声的适应性更强,但在稀疏性和噪声抵抗方面,Ridge 和 SBL 均能提供较为稳健的表现.

5.实验代码(python)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from scipy.sparse import rand as sparse_rand
from scipy.stats import norm
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score, explained_variance_score, max_error
 
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 300
np.random.seed(42)
n_samples, n_features = 1000, 2000  
density_levels = [0.01, 0.05, 0.1] 
noise_levels = np.linspace(0.1, 1.0, 20)  
ridge_alpha = 0.01
sbl_alpha = 1e-6

def sparsity(coef, threshold=1e-3):
    return np.sum(np.abs(coef) > threshold) / len(coef)
results = []
 
for density in density_levels:
    X = sparse_rand(n_samples, n_features, density=density, format='csr').toarray()
    true_coef = np.zeros(n_features)
    non_zero_indices = np.random.choice(n_features, 30, replace=False)   
    true_coef[non_zero_indices] = np.random.normal(loc=0, scale=1, size=30)

    noise_std = 0.05
    y = X @ true_coef + norm.rvs(scale=noise_std, size=n_samples)
    
    ridge = Ridge(alpha=ridge_alpha)
    ridge.fit(X, y)
    sbl_solution = np.linalg.solve(X.T @ X + sbl_alpha * np.eye(n_features), X.T @ y)

    results.append({
        'density': density,
        'Ridge_sparsity': sparsity(ridge.coef_),
        'SBL_sparsity': sparsity(sbl_solution),
        'Ridge_L1': np.sum(np.abs(ridge.coef_)),
        'SBL_L1': np.sum(np.abs(sbl_solution)),
        'Ridge_L2': np.sqrt(np.sum(ridge.coef_**2)),
        'SBL_L2': np.sqrt(np.sum(sbl_solution**2)),
        'ridge_mse_errors': [], 'sbl_mse_errors': [],
        'ridge_mae_errors': [], 'sbl_mae_errors': [],
        'ridge_r2_scores': [], 'sbl_r2_scores': [],
        'ridge_exp_var_scores': [], 'sbl_exp_var_scores': [],
        'ridge_rmse_errors': [], 'sbl_rmse_errors': [],
        'ridge_max_errors': [], 'sbl_max_errors': []
    })

    for noise in noise_levels:
        y_noisy = X @ true_coef + norm.rvs(scale=noise, size=n_samples)
        ridge.fit(X, y_noisy)
        sbl_solution_noisy = np.linalg.solve(X.T @ X + sbl_alpha * np.eye(n_features), X.T @ y_noisy)

        results[-1]['ridge_mse_errors'].append(mean_squared_error(ridge.coef_, true_coef))
        results[-1]['sbl_mse_errors'].append(mean_squared_error(sbl_solution_noisy, true_coef))
        results[-1]['ridge_mae_errors'].append(mean_absolute_error(ridge.coef_, true_coef))
        results[-1]['sbl_mae_errors'].append(mean_absolute_error(sbl_solution_noisy, true_coef))
        results[-1]['ridge_r2_scores'].append(r2_score(y_noisy, X @ ridge.coef_))
        results[-1]['sbl_r2_scores'].append(r2_score(y_noisy, X @ sbl_solution_noisy))
        results[-1]['ridge_exp_var_scores'].append(explained_variance_score(y_noisy, X @ ridge.coef_))
        results[-1]['sbl_exp_var_scores'].append(explained_variance_score(y_noisy, X @ sbl_solution_noisy))
        results[-1]['ridge_rmse_errors'].append(np.sqrt(mean_squared_error(ridge.coef_, true_coef)))
        results[-1]['sbl_rmse_errors'].append(np.sqrt(mean_squared_error(sbl_solution_noisy, true_coef)))
        results[-1]['ridge_max_errors'].append(max_error(ridge.coef_, true_coef))
        results[-1]['sbl_max_errors'].append(max_error(sbl_solution_noisy, true_coef))

fig, axes = plt.subplots(3, 5, figsize=(25, 15))
for i, res in enumerate(results):
    axes[i, 0].bar(['Ridge', 'SBL'], [res['Ridge_sparsity'], res['SBL_sparsity']], color=['#ff7f0e', '#9467bd'])
    axes[i, 0].set_title(f'稀疏度比较 (密度={res["density"]})')
    axes[i, 0].set_ylabel('稀疏度')
    axes[i, 0].grid(True, linestyle='--', alpha=0.6)

    axes[i, 1].plot(noise_levels, res['ridge_mse_errors'], label='Ridge MSE', marker='x', color='#ff7f0e')
    axes[i, 1].plot(noise_levels, res['sbl_mse_errors'], label='SBL MSE', marker='s', color='#9467bd')
    axes[i, 1].set_title('均方误差 (MSE)')
    axes[i, 1].set_xlabel('噪声水平')
    axes[i, 1].grid(True, linestyle='--', alpha=0.6)

    axes[i, 2].plot(noise_levels, res['ridge_rmse_errors'], label='Ridge RMSE', marker='x', color='#ff7f0e')
    axes[i, 2].plot(noise_levels, res['sbl_rmse_errors'], label='SBL RMSE', marker='s', color='#9467bd')
    axes[i, 2].set_title('均方根误差 (RMSE)')
    axes[i, 2].set_xlabel('噪声水平')
    axes[i, 2].grid(True, linestyle='--', alpha=0.6)

    axes[i, 3].plot(noise_levels, res['ridge_max_errors'], label='Ridge Max Error', marker='x', color='#ff7f0e')
    axes[i, 3].plot(noise_levels, res['sbl_max_errors'], label='SBL Max Error', marker='s', color='#9467bd')
    axes[i, 3].set_title('最大误差')
    axes[i, 3].set_xlabel('噪声水平')
    axes[i, 3].grid(True, linestyle='--', alpha=0.6)

    axes[i, 4].plot(noise_levels, res['ridge_exp_var_scores'], label='Ridge 解释方差', marker='x', color='#ff7f0e')
    axes[i, 4].plot(noise_levels, res['sbl_exp_var_scores'], label='SBL 解释方差', marker='s', color='#9467bd')
    axes[i, 4].set_title('解释方差')
    axes[i, 4].set_xlabel('噪声水平')
    axes[i, 4].grid(True, linestyle='--', alpha=0.6)

plt.tight_layout()
plt.show()

posted on 2024-12-04 23:09  咸鱼不翻身呀  阅读(1099)  评论(0)    收藏  举报