贝叶斯回归#
贝叶斯回归是一种基于贝叶斯统计推断的回归方法。它通过引入先验分布来表达对参数的不确定性,并利用观测数据来更新参数的后验分布。假设我们有一个训练集包含\(N\)个样本,每个样本由输入特征\(X\)和对应的输出标签\(y\)组成。要经过的步骤是参数建模 -> 后验推断 -> 参数估计和预测。
优缺点:
贝叶斯回归引入先验知识。适用于小样本、高噪声以及需要考虑模型不确定性的数据。
计算复杂度较高,需要进行概率推断和参数估计,不适用于高维数据。
下面是使用Python和PyMC3库实现贝叶斯线性回归的示例代码:
import pymc3 as pm
import numpy as np
# 构造训练集
X = np.random.randn(100, 2)
w_true = np.array([3, 5])
y = X.dot(w_true) + np.random.randn(100)
# 创建贝叶斯模型
with pm.Model() as model:
# 定义参数的先验分布
w = pm.Normal('w', mu=0, sd=1, shape=2)
sigma = pm.HalfNormal('sigma', sd=1)
# 定义输出标签的条件分布
y_obs = pm.Normal('y_obs', mu=pm.math.dot(X, w), sd=sigma, observed=y)
# 进行后验推断
trace = pm.sample(1000, tune=1000)
# 输出参数估计结果
print("参数估计结果:")
print(pm.summary(trace)['mean'])
# 进行预测
x_new = np.array([[1, 2], [3, 4]]) # 新的输入特征
with model:
post_pred = pm.sample_posterior_predictive(trace, samples=1000, vars=[y_obs])
y_pred_mean = np.mean(post_pred['y_obs'], axis=0)
print("预测结果:")
print(y_pred_mean)
/home/runner/.local/lib/python3.10/site-packages/theano/scalar/basic.py:2412: FutureWarning: In the future `np.bool` will be defined as the corresponding NumPy scalar.
self.ctor = getattr(np, o_type.dtype)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[1], line 1
----> 1 import pymc3 as pm
2 import numpy as np
4 # 构造训练集
File ~/.local/lib/python3.10/site-packages/pymc3/__init__.py:23
20 import platform
22 import semver
---> 23 import theano
25 _log = logging.getLogger("pymc3")
27 if not logging.root.handlers:
File ~/.local/lib/python3.10/site-packages/theano/__init__.py:83
75 # This is the api version for ops that generate C code. External ops
76 # might need manual changes if this number goes up. An undefined
77 # __api_version__ can be understood to mean api version 0.
78 #
79 # This number is not tied to the release version and should change
80 # very rarely.
81 __api_version__ = 1
---> 83 from theano import scalar, tensor
84 from theano.compile import (
85 In,
86 Mode,
(...)
93 shared,
94 )
95 from theano.compile.function import function, function_dump
File ~/.local/lib/python3.10/site-packages/theano/scalar/__init__.py:1
----> 1 from .basic import *
2 from .basic_scipy import *
File ~/.local/lib/python3.10/site-packages/theano/scalar/basic.py:2460
2456 else:
2457 return s
-> 2460 convert_to_bool = Cast(bool, name="convert_to_bool")
2461 convert_to_int8 = Cast(int8, name="convert_to_int8")
2462 convert_to_int16 = Cast(int16, name="convert_to_int16")
File ~/.local/lib/python3.10/site-packages/theano/scalar/basic.py:2412, in Cast.__init__(self, o_type, name)
2410 super().__init__(specific_out(o_type), name=name)
2411 self.o_type = o_type
-> 2412 self.ctor = getattr(np, o_type.dtype)
File ~/.local/lib/python3.10/site-packages/numpy/__init__.py:324, in __getattr__(attr)
319 warnings.warn(
320 f"In the future `np.{attr}` will be defined as the "
321 "corresponding NumPy scalar.", FutureWarning, stacklevel=2)
323 if attr in __former_attrs__:
--> 324 raise AttributeError(__former_attrs__[attr])
326 if attr == 'testing':
327 import numpy.testing as testing
AttributeError: module 'numpy' has no attribute 'bool'.
`np.bool` was a deprecated alias for the builtin `bool`. To avoid this error in existing code, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here.
The aliases was originally deprecated in NumPy 1.20; for more details and guidance see the original release note at:
https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
贝叶斯岭回归#
贝叶斯岭回归(Bayesian Ridge Regression)是一种基于贝叶斯统计推断的回归方法,结合了岭回归和贝叶斯推断的思想。
具体步骤如下:
假设模型为:
\(y = Xw + ε\) 其中,\(y\)是目标变量,\(X\)是特征矩阵,\(w\)是待估计的参数向量,\(ε\)是误差项。
输入:特征矩阵 \(X\)(大小为 \(n \times p\)),目标变量向量 \(y\)(长度为 \(n\))
输出:参数估计值 \(w\)
定义先验分布:假设参数 \(w\) 的先验分布为 \(p(w)\)。
计算后验分布:根据贝叶斯定理,可以得到参数 \(w\) 的后验分布:
\( p(w|X, y) = \frac{p(y|X, w) \cdot p(w)}{p(y|X)} \)
其中,\(p(y|X, w)\) 是给定参数 \(w\) 条件下观测数据 \(y\) 的概率密度函数,\(p(w)\) 是参数 \(w\) 的先验分布,\(p(y|X)\) 是边际似然函数。
参数估计:通过后验分布可以获得参数的点估计或分布估计。
点估计:例如,使用后验分布的均值作为参数的点估计:
\( \hat{w} = E[w|X, y] = \int w \cdot p(w|X, y) dw \)
分布估计:通过后验分布得到参数的概率分布,用于描述参数的不确定性:
\( p(w|X, y) \)
通过对后验分布进行采样或使用解析的数学表达式,可以获得对参数 \(w\) 的估计结果,其中包括点估计和不确定性估计。
下面是使用Python和Scikit-learn库实现贝叶斯岭回归的示例代码:
from sklearn import linear_model
X = [[0., 0.], [1., 1.], [2., 2.], [3., 3.]]
Y = [0., 1., 2., 3.]
# 创建贝叶斯岭回归模型
reg = linear_model.BayesianRidge()
# 拟合模型
reg.fit(X, Y)
# 输出参数估计结果
print("参数估计结果:")
print(reg.coef_)
# 进行预测
y_pred = reg.predict([[1, 0.]])
参数估计结果:
[0.49999993 0.49999993]
主动相关决策理论 - ARD#
ARDRegression类似于贝叶斯岭回归(Bayesian Ridge Regression),但具有更强的稀疏性。这是因为ARDRegression引入了不同于贝叶斯岭回归的先验假设,即权重 \(w\) 的分布不再是球形的高斯分布,而是轴对齐的椭圆高斯分布。
ARDRegression中的每个权重 \(wi\) 都有一个单独的标准差 \(λ_i\) 。所有 \(λ_i\) 的先验分布由超参数 \(λ1\) 、\(λ2\) 等确定,通常使用相同的 \(\gamma\) 分布。
ARDRegression可以用于特征选择,因为它倾向于将不相关或弱相关的特征的权重设为0,从而实现了稀疏性。这使得模型更容易解释,并且可以提高泛化性能。
不过ARD也比较慢。
下面给个sklearn的例子:
from sklearn.datasets import make_regression
from sklearn.linear_model import ARDRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 生成随机回归数据集
X, y = make_regression(n_samples=100, n_features=10, noise=0.1, random_state=42)
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建并拟合ARDRegression模型
model = ARDRegression()
model.fit(X_train, y_train)
# 使用模型进行预测
y_pred = model.predict(X_test)
# 计算均方误差(Mean Squared Error)
mse = mean_squared_error(y_test, y_pred)
print("Mean Squared Error: ", mse)
Mean Squared Error: 0.010270127022996813
参考#
贝叶斯回归:使用 PyMC3 实现贝叶斯回归 https://baijiahao.baidu.com/s?id=1745363357212714786&wfr=spider&for=pc