1 个不稳定版本

0.1.0 2022 年 12 月 6 日

#481机器学习

每月 23 次下载

MIT/Apache

52KB
1K SLoC

variational-regression

使用变分推断训练的回归模型

动机

此库提供了贝叶斯回归模型的实现,通过优化对对数似然的下界来学习参数值。使用变分推断的好处是训练效率高,我们有一个定义良好的目标函数来优化。贝叶斯方法还可以将正则化自然地纳入模型。

线性回归

模型如下指定

p(y | θ) = ∏ N(yi | θTxi, β-1)

p(θ | α) = ∏ N(θj | 0, αj-1)

p(α) = ∏ Gam(αj | a0, b0)

p(β) = Gam(β | c0, d0)

使用以下符号

y = 标签

x = 特征

θ = 模型权重

α = 权重精度(逆方差)

β = 噪声精度(逆方差)

逻辑回归

模型如下指定

p(y | θ) = ∏ σ(θTxi)yi {1 - σ(θTxi)}1-yi

p(θ | α) = ∏ N(θj | 0, αj-1)

p(α) = ∏ Gam(αj | a0, b0)

使用以下符号

y = 标签

x = 特征

θ = 模型权重

α = 权重精度(逆方差)

σ = 逻辑sigmoid函数

参考

这里实现的模型在很大程度上基于 Bishop 在 2006 年的《模式识别与机器学习》第 10 章中提出的模型。然而,一个关键的区别是,在这里,每个模型权重都有自己的精度分布,线性回归模型的噪声项也是如此。

示例

use variational_regression::*;

fn main() -> Result<(), RegressionError> {

    // construct features
    let features: &[&[f64]] = &[
        &[-0.2, -0.9, -0.5, 0.3],
        &[0.6, 0.3, 0.3, -0.4],
        &[0.9, -0.4, -0.5, -0.6],
        &[-0.7, 0.8, 0.3, -0.3],
        &[-0.5, -0.7, -0.1, 0.8],
        &[0.5, 0.5, 0.0, 0.1],
        &[0.1, -0.0, 0.0, -0.2],
        &[0.4, 0.0, 0.2, 0.0],
        &[-0.2, 0.9, -0.1, -0.9],
        &[0.1, 0.4, -0.5, 0.9],
    ];
    
    // construct labels
    let labels: &[f64] = &[-0.4, 0.1, -0.8, 0.5, 0.6, -0.2, 0.0, 0.7, -0.3, 0.2];
    
    // configure and train model
    let config = LinearTrainConfig::default();
    let model = VariationalLinearRegression::train(features, labels, &config)?;
    
    // inspect model bias
    if let Some(bias) = model.bias() {
        println!("Bias: {}", bias);
    }

    // inspect model weights
    for (ind, weight) in model.weights().iter().enumerate() {
        println!("Weight {}: {}", ind + 1, weight);
    }

    // inspect noise variance
    println!("Noise Variance: {}", 1.0 / model.noise_precision.mean());
    
    // get predictive distribution
    let prediction = model.predict(&[0.1, -0.5, 0.3, 0.9])?;
    println!("Predictive mean: {}", prediction.mean());
    
    Ok(())
}
use variational_regression::*;

fn main() -> Result<(), RegressionError> {

    // construct features
    let features: &[&[f64]] = &[
        &[-0.2, -0.9, -0.5, 0.3],
        &[0.6, 0.3, 0.3, -0.4],
        &[0.9, -0.4, -0.5, -0.6],
        &[-0.7, 0.8, 0.3, -0.3],
        &[-0.5, -0.7, -0.1, 0.8],
        &[0.5, 0.5, 0.0, 0.1],
        &[0.1, -0.0, 0.0, -0.2],
        &[0.4, 0.0, 0.2, 0.0],
        &[-0.2, 0.9, -0.1, -0.9],
        &[0.1, 0.4, -0.5, 0.9],
    ];
    
    // construct labels
    let labels: &[bool] = &[true, false, true, false, true, false, true, false, true, false];
    
    // configure and train model
    let config = LogisticTrainConfig::default();
    let model = VariationalLogisticRegression::train(features, labels, &config)?;
    
    // inspect model bias
    if let Some(bias) = model.bias() {
        println!("Bias: {}", bias);
    }

    // inspect model weights
    for (ind, weight) in model.weights().iter().enumerate() {
        println!("Weight {}: {}", ind + 1, weight);
    }

    // get predictive distribution
    let prediction = model.predict(&[0.1, -0.5, 0.3, 0.9])?;
    println!("Predictive mean: {}", prediction.mean());

    Ok(())
}

依赖项

~4MB
~82K SLoC