哈喽,大家好~
今儿和大家一起来聊聊,贝叶斯回归~
如果模型预测了一个数,但这个数到底靠不靠谱,它能不能一起告诉你?
普通线性回归通常只给我们一个预测值,而贝叶斯回归会进一步估计参数的不确定性,并给出预测区间。也就是说,它不仅回答“预测是多少”,还会告诉你“这个预测有多稳”~
01直观理解贝叶斯回归
假设我们要根据房屋面积预测房价~
普通线性回归会努力找到一条最合适的直线:
其中, 是房屋面积, 是房价, 是模型需要学习的参数。
但现实中的数据并不完美。同样面积的房子,因为地段、装修、楼层不同,价格也会有差异。
所以,贝叶斯回归不会认为参数一定是某个固定值,而是认为参数本身也有一个概率分布:参数可能落在某个范围内,只是有些取值更可信。
最后模型输出的也不只是一个结果,而是一个分布。
例如:预测房价为 200 万,95% 的可信区间是 185 万到 216 万。
一句话,贝叶斯回归 = 预测结果 + 不确定性分析。
02核心原理:先验、似然和后验
贝叶斯线性回归的基本形式仍然是:
这里的 是特征矩阵, 是模型参数, 是随机误差。
我们通常假设误差服从高斯分布:
同时,为了避免模型参数过大,给参数设置一个高斯先验:
其中:
-
控制参数先验的强弱; -
控制观测噪声的大小; -
是单位矩阵。
训练完成后,参数的后验分布仍然是高斯分布:
其中:
你可以这样理解:
-
是模型认为最合理的参数中心; -
描述参数的不确定性; -
数据越充分,通常参数越稳定,不确定性越小。
对于新样本 ,预测结果也服从一个高斯分布:
前面的 是预测均值,后面的部分表示预测方差。
总之就是说,离训练数据越远,模型通常越没有把握,预测区间也会变宽。
03完整案例
这里我们构造一组数据。真实关系是一条带噪声的非线性曲线,然后使用多项式特征配合 BayesianRidge 完成建模。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import BayesianRidge
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_squared_error, r2_score
# 1. 构造数据
np.random.seed(42)
x = np.linspace(-3, 3, 180)
y = 1.5 * np.sin(1.4 * x) + 0.18 * x + np.random.normal(0, 0.22, len(x))
X = x.reshape(-1, 1)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 2. 多项式特征 + 贝叶斯回归
model = Pipeline([
("poly", PolynomialFeatures(degree=8, include_bias=False)),
("bayes", BayesianRidge(
alpha_1=1e-6,
alpha_2=1e-6,
lambda_1=1e-6,
lambda_2=1e-6
))
])
model.fit(X_train, y_train)
# 3. 预测均值和标准差
x_plot = np.linspace(-3.4, 3.4, 400).reshape(-1, 1)
y_mean, y_std = model.predict(x_plot, return_std=True)
y_pred, test_std = model.predict(X_test, return_std=True)
print("RMSE:", mean_squared_error(y_test, y_pred) ** 0.5)
print("R2:", r2_score(y_test, y_pred))
# 4. 绘图
fig, axes = plt.subplots(1, 2, figsize=(15, 5))
# 图一:预测曲线和不确定性区间
axes[0].scatter(
X_train, y_train, color="#00B4D8", s=35,
alpha=0.75, label="Train data"
)
axes[0].scatter(
X_test, y_test, color="#FF006E", s=55,
edgecolors="white", label="Test data"
)
axes[0].plot(
x_plot, y_mean, color="#8338EC",
linewidth=3, label="Bayesian prediction"
)
axes[0].fill_between(
x_plot.ravel(),
y_mean - 1.96 * y_std,
y_mean + 1.96 * y_std,
color="#FFBE0B", alpha=0.3,
label="Approx. 95% interval"
)
axes[0].set_title("Prediction with Uncertainty")
axes[0].set_xlabel("Feature x")
axes[0].set_ylabel("Target y")
axes[0].legend()
axes[0].grid(alpha=0.25)
# 图二:测试集预测误差分析
error = y_test - y_pred
scatter = axes[1].scatter(
y_pred, error,
c=np.abs(error), cmap="plasma",
s=70, edgecolors="black", alpha=0.85
)
axes[1].axhline(0, color="#264653", linestyle="--", linewidth=2)
axes[1].errorbar(
y_pred, np.zeros_like(y_pred),
yerr=1.96 * test_std,
fmt="none", ecolor="#06D6A0",
alpha=0.45, capsize=3
)
axes[1].set_title("Residuals and Predictive Uncertainty")
axes[1].set_xlabel("Predicted value")
axes[1].set_ylabel("Residual: actual - predicted")
axes[1].grid(alpha=0.25)
plt.colorbar(scatter, ax=axes[1], label="Absolute residual")
plt.tight_layout()
plt.show()
第一张图中,紫色曲线是模型的预测均值,黄色区域是近似的 95% 预测区间。
如果某个位置的黄色区域很窄,说明模型在这里比较有把握;如果区间明显变宽,说明该区域的数据较少,模型不确定性更高。
这也是贝叶斯回归和普通回归很重要的区别:它把“预测风险”也展示出来了。
第二张图是残差分析图。
横轴是预测值,纵轴是残差:
如果模型表现较好,散点应该大致围绕 上下分布。颜色越亮,表示绝对误差越大。
图中的绿色误差线表示预测不确定性范围。如果某些点的真实残差明显超出了误差范围,说明模型可能低估了噪声,或者这些样本存在异常情况。
04贝叶斯回归什么时候用
贝叶斯回归特别适合下面几类场景:
样本量不大
先验可以帮助模型避免参数过度波动。
需要判断预测是否可靠
比如金融风险、医疗预测、工程安全等问题,单纯输出一个数往往不够。
特征数量较多,担心过拟合
贝叶斯先验本身带有正则化效果,可以抑制过大的参数。
希望获得预测区间
不只看平均误差,还要知道模型在哪些区域不确定。
实际使用时,多项式次数不能设置得太高。次数越高,模型越容易拟合训练数据中的噪声。你可以尝试调整 degree,观察预测曲线和不确定性区间的变化。
总结
贝叶斯回归的核心思想并不复杂:把模型参数看成一个概率分布,通过先验和数据共同得到后验分布,最终同时输出预测值与不确定性。
在代码实现中,BayesianRidge 已经帮我们完成了后验估计和超参数学习。真正分析结果时,不要只看 RMSE 和
,还要观察预测区间以及残差是否合理。

