后验概率最大化(MAP)估计算法原理以及相具体的应用实例附C++代码示例

1. MAP估计基本原理

MAP(Maximum A Posteriori,最大后验概率估计)是贝叶斯推断中的重要概念,它的目标是:

给定观测数据,找到使得后验概率最大的参数值。

公式化表示:
[ θ MAP = arg ⁡ max ⁡ θ P ( θ ∣ x ) ] [ \theta_{\text{MAP}} = \arg\max_{\theta} P(\theta | x) ] [θMAP=argθmaxP(θx)]
其中:

  • ( θ ) ( \theta ) (θ) 是我们要估计的参数,
  • ( x ) ( x ) (x) 是观测数据,
  • ( P ( θ ∣ x ) ) ( P(\theta | x) ) (P(θx)) 是参数在观测数据下的后验概率。

利用贝叶斯公式展开:
[ P ( θ ∣ x ) = P ( x ∣ θ ) P ( θ ) P ( x ) ] [ P(\theta | x) = \frac{P(x|\theta) P(\theta)}{P(x)} ] [P(θx)=P(x)P(xθ)P(θ)]
其中:

  • ( P ( x ∣ θ ) ) ( P(x|\theta) ) (P(xθ)) 是似然(likelihood),
  • ( P ( θ ) ) ( P(\theta) ) (P(θ)) 是先验(prior),
  • ( P ( x ) ) ( P(x) ) (P(x)) 是证据(evidence),与参数无关,可忽略在优化中。

所以 MAP 估计可以等价为最大化:
[ θ MAP = arg ⁡ max ⁡ θ P ( x ∣ θ ) P ( θ ) ] [ \theta_{\text{MAP}} = \arg\max_{\theta} P(x|\theta) P(\theta) ] [θMAP=argθmaxP(xθ)P(θ)]
也可以取对数(为了数值稳定和方便求导):
[ θ MAP = arg ⁡ max ⁡ θ ( log ⁡ P ( x ∣ θ ) + log ⁡ P ( θ ) ) ] [ \theta_{\text{MAP}} = \arg\max_{\theta} \left( \log P(x|\theta) + \log P(\theta) \right) ] [θMAP=argθmax(logP(xθ)+logP(θ))]
总结:

  • MLE(最大似然估计)只最大化 ( P ( x ∣ θ ) ) ( P(x|\theta) ) (P(xθ))不考虑先验
  • MAP 估计既考虑似然 ( P ( x ∣ θ ) ) ( P(x|\theta) ) (P(xθ)),又考虑先验 ( P ( θ ) ) ( P(\theta) ) (P(θ))

2. MAP推导示例 —— 估计正态分布均值

假设观测数据集 ( x = { x 1 , x 2 , . . . , x N } ) ( x = \{x_1, x_2, ..., x_N\} ) (x={x1,x2,...,xN}) 是从均值为 ( μ ) ( \mu ) (μ)、方差为已知 ( σ 2 ) ( \sigma^2 ) (σ2) 的正态分布中采样得到的。
我们要用 MAP 估计 ( μ ) ( \mu ) (μ)

  • 似然函数(假设独立同分布):
    [ P ( x ∣ μ ) = ∏ i = 1 N 1 2 π σ 2 exp ⁡ ( − ( x i − μ ) 2 2 σ 2 ) ] [ P(x|\mu) = \prod_{i=1}^N \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left( -\frac{(x_i-\mu)^2}{2\sigma^2} \right) ] [P(xμ)=i=1N2πσ2 1exp(2σ2(xiμ)2)]
    取对数似然:
    [ log ⁡ P ( x ∣ μ ) = − N 2 log ⁡ ( 2 π σ 2 ) − 1 2 σ 2 ∑ i = 1 N ( x i − μ ) 2 ] [ \log P(x|\mu) = -\frac{N}{2} \log(2\pi\sigma^2) - \frac{1}{2\sigma^2} \sum_{i=1}^N (x_i-\mu)^2 ] [logP(xμ)=2Nlog(2πσ2)2σ21i=1N(xiμ)2]
  • 假设先验 ( μ ∼ N ( μ 0 , σ 0 2 ) ) ( \mu \sim \mathcal{N}(\mu_0, \sigma_0^2) ) (μN(μ0,σ02)),即:
    [ P ( μ ) = 1 2 π σ 0 2 exp ⁡ ( − ( μ − μ 0 ) 2 2 σ 0 2 ) ] [ P(\mu) = \frac{1}{\sqrt{2\pi\sigma_0^2}} \exp\left( -\frac{(\mu-\mu_0)^2}{2\sigma_0^2} \right) ] [P(μ)=2πσ02 1exp(2σ02(μμ0)2)]
    取对数先验:
    [ log ⁡ P ( μ ) = − 1 2 log ⁡ ( 2 π σ 0 2 ) − ( μ − μ 0 ) 2 2 σ 0 2 ] [ \log P(\mu) = -\frac{1}{2} \log(2\pi\sigma_0^2) - \frac{(\mu-\mu_0)^2}{2\sigma_0^2} ] [logP(μ)=21log(2πσ02)2σ02(μμ0)2]
  • 总目标:
    [ θ MAP = arg ⁡ max ⁡ μ ( log ⁡ P ( x ∣ μ ) + log ⁡ P ( μ ) ) ] [ \theta_{\text{MAP}} = \arg\max_{\mu} \left( \log P(x|\mu) + \log P(\mu) \right) ] [θMAP=argμmax(logP(xμ)+logP(μ))]
    去掉无关常数后,最大化:
    [ − 1 2 σ 2 ∑ i = 1 N ( x i − μ ) 2 − 1 2 σ 0 2 ( μ − μ 0 ) 2 ] [ -\frac{1}{2\sigma^2} \sum_{i=1}^N (x_i-\mu)^2 - \frac{1}{2\sigma_0^2} (\mu-\mu_0)^2 ] [2σ21i=1N(xiμ)22σ021(μμ0)2]
    即最小化:
    [ ∑ i = 1 N ( x i − μ ) 2 + σ 2 σ 0 2 ( μ − μ 0 ) 2 ] [ \sum_{i=1}^N (x_i-\mu)^2 + \frac{\sigma^2}{\sigma_0^2} (\mu-\mu_0)^2 ] [i=1N(xiμ)2+σ02σ2(μμ0)2]
    展开、对 ( μ ) ( \mu ) (μ) 求导并令导数为零,得到:
    [ μ MAP = σ 0 2 ∑ i = 1 N x i + σ 2 μ 0 N σ 0 2 + σ 2 ] [ \mu_{\text{MAP}} = \frac{\sigma_0^2 \sum_{i=1}^N x_i + \sigma^2 \mu_0}{N\sigma_0^2 + \sigma^2} ] [μMAP=Nσ02+σ2σ02i=1Nxi+σ2μ0]
    直观理解:
  • 当先验方差 ( σ 0 2 ) ( \sigma_0^2 ) (σ02) 很大时,先验很弱,MAP 估计趋近于 MLE(样本均值)。
  • 当先验方差小,先验很强,结果更接近先验均值 ( μ 0 ) ( \mu_0 ) (μ0)

3. MAP应用实例

常见的 MAP 应用领域包括:

  • SLAM后端优化(g2o, GTSAM):地图和轨迹估计通常是 MAP 问题。
  • 机器学习(L2正则化):加了正则项的回归可解释为 MAP。
  • 信号处理:滤波器设计中有 MAP估计噪声。
  • 计算机视觉:图像配准、姿态估计等。
  • NLP生成模型:文本生成时选概率最大的输出。

4. C++代码示例 —— 正态分布均值的MAP估计

下面给出简单的 C++ 代码示例:

#include <iostream>
#include <vector>
#include <numeric> // std::accumulate// 计算均值
double compute_mean(const std::vector<double>& data) {return std::accumulate(data.begin(), data.end(), 0.0) / data.size();
}// MAP估计
double map_estimate(const std::vector<double>& data, double sigma2, double mu0, double sigma0_2) {double N = static_cast<double>(data.size());double sum_x = std::accumulate(data.begin(), data.end(), 0.0);double numerator = sigma0_2 * sum_x + sigma2 * mu0;double denominator = N * sigma0_2 + sigma2;return numerator / denominator;
}int main() {// 观测数据std::vector<double> x = {1.2, 1.8, 2.0, 1.5, 2.2};// 已知观测噪声方差double sigma2 = 0.1;// 先验均值和方差double mu0 = 2.0;double sigma0_2 = 0.5;double mu_map = map_estimate(x, sigma2, mu0, sigma0_2);std::cout << "MAP估计的均值为: " << mu_map << std::endl;return 0;
}

输出示例:

MAP估计的均值为: 1.87321

总结一句话

MAP估计 = 在最大似然上加上先验知识,让推断更加鲁棒。


5. MAP下拟合直线示例:推导

假设我们有 ( N ) ( N ) (N) 个观测点 ( ( x i , y i ) ) ( (x_i, y_i) ) ((xi,yi)),我们想拟合一条直线:
[ y = a x + b ] [ y = ax + b ] [y=ax+b]
其中参数 ( a , b ) ( a, b ) (a,b) 是我们要估计的。

  • 似然模型(假设观测有高斯噪声):
    [ y i = a x i + b + ϵ i , ϵ i ∼ N ( 0 , σ 2 ) ] [ y_i = a x_i + b + \epsilon_i, \quad \epsilon_i \sim \mathcal{N}(0, \sigma^2) ] [yi=axi+b+ϵi,ϵiN(0,σ2)]
    所以似然为:
    [ P ( y i ∣ x i , a , b ) ∝ exp ⁡ ( − ( y i − ( a x i + b ) ) 2 2 σ 2 ) ] [ P(y_i|x_i, a, b) \propto \exp\left( -\frac{(y_i - (a x_i + b))^2}{2\sigma^2} \right) ] [P(yixi,a,b)exp(2σ2(yi(axi+b))2)]
  • 先验模型
    假设我们对 ( a ) ( a ) (a) ( b ) ( b ) (b) 有正则化先验(例如,偏好较小的斜率和截距):
    [ P ( a , b ) ∝ exp ⁡ ( − λ 2 ( a 2 + b 2 ) ) ] [ P(a, b) \propto \exp\left( -\frac{\lambda}{2} (a^2 + b^2) \right) ] [P(a,b)exp(2λ(a2+b2))]
  • MAP目标函数(取负对数,变成最小化问题):
    [ Cost ( a , b ) = ∑ i = 1 N ( y i − ( a x i + b ) ) 2 + λ ( a 2 + b 2 ) ] [ \text{Cost}(a, b) = \sum_{i=1}^N (y_i - (a x_i + b))^2 + \lambda (a^2 + b^2) ] [Cost(a,b)=i=1N(yi(axi+b))2+λ(a2+b2)]
    就是常规的最小二乘项 + 正则项!
    这个目标就是典型的带L2正则化的线性回归(也叫Ridge Regression)。

6. 用Eigen实现完整C++版

下面给你完整示例,包括矩阵推导、解法、绘图。

基于Eigen的 C++代码示例

#include <iostream>
#include <vector>
#include <Eigen/Dense>// 用于生成一些模拟数据
void generate_data(std::vector<double>& xs, std::vector<double>& ys, double true_a, double true_b, double noise_std, int N) {std::default_random_engine generator;std::normal_distribution<double> noise(0.0, noise_std);xs.resize(N);ys.resize(N);for (int i = 0; i < N; ++i) {xs[i] = i * 0.1;  // 让x均匀增长ys[i] = true_a * xs[i] + true_b + noise(generator);}
}// MAP线性回归:最小化 (Ax - y)^2 + lambda * ||x||^2
void map_fit(const std::vector<double>& xs, const std::vector<double>& ys, double lambda, double& est_a, double& est_b) {int N = xs.size();Eigen::MatrixXd A(N, 2);Eigen::VectorXd y(N);for (int i = 0; i < N; ++i) {A(i, 0) = xs[i];A(i, 1) = 1.0;y(i) = ys[i];}// 正规方程带正则项:(A^T A + lambda * I) x = A^T yEigen::Matrix2d ATA = A.transpose() * A;Eigen::Vector2d ATy = A.transpose() * y;ATA += lambda * Eigen::Matrix2d::Identity(); // 加上正则化Eigen::Vector2d x = ATA.ldlt().solve(ATy);est_a = x(0);est_b = x(1);
}int main() {std::vector<double> xs, ys;double true_a = 2.0, true_b = 1.0;generate_data(xs, ys, true_a, true_b, 0.1, 50);double est_a = 0.0, est_b = 0.0;double lambda = 1.0; // 正则化强度map_fit(xs, ys, lambda, est_a, est_b);std::cout << "真实值: a = " << true_a << ", b = " << true_b << std::endl;std::cout << "MAP估计: a = " << est_a << ", b = " << est_b << std::endl;return 0;
}

7. 总结一下

对象含义
似然拟合观测数据的准确性
先验防止参数过大(正则化)
MAP估计似然 × 先验的最大化
公式最小化误差项 + 正则项

直观理解:

  • 你希望拟合数据,同时又不希望参数太大(比如防止过拟合)。
  • 正则化参数 ( λ ) ( \lambda ) (λ) 越大,先验越强,越倾向于把 ( a , b ) ( a, b ) (a,b) 拉向 0。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78683.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

16、路由守卫:设置魔法结界——React 19 React Router

一、魔法结界的本质 "路由守卫是霍格沃茨城堡的隐身斗篷&#xff0c;在时空裂隙中精准控制维度跃迁&#xff01;" 魔法部交通司官员挥舞魔杖&#xff0c;React Router 的嵌套路由在空中交织成星轨矩阵。 ——基于《国际魔法联合会》第7号时空协议&#xff0c;路由守…

从车道检测项目入门open cv

从车道检测项目入门open cv 前提声明&#xff1a;非常感谢b站up主 嘉然今天吃带变&#xff0c;感谢其视频的帮助。同时希望各位大佬积积极提出宝贵的意见。&#x1f60a;&#x1f60a;&#x1f60a;(❁◡❁)(●’◡’●)╰(▽)╯ github地址&#xff1a;https://github.com/liz…

【行业特化篇3】制造业简历优化指南:技术参数与标准化流程的关键词植入艺术

写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…

如何在本地部署小智服务器:从源码到全模块运行的详细步骤

小智聊天机器人本地后台服务器源码全模块部署 作者&#xff1a;林甲酸 -不是小女子也不是女汉子 是大女子 更新日期&#xff1a;2025年4月29日 &#x1f3af; 前言&#xff1a;为什么要写这篇教程&#xff1f; 上周按照虾哥小智服务器的教程去部署本地后台&#xff0c;我用的是…

github开源项目添加开源协议,使用很简单

直接在 GitHub 网页上创建 进入你的 GitHub 仓库 打开你的项目仓库页面&#xff08;如 https://github.com/用户名/仓库名&#xff09;。 点击 "Add file" → "Create new file" 在仓库主页&#xff0c;点击右上角的 "Add file" 按钮&#xff…

8.idea创建maven项目(使用Log4j日志记录框架+Log4j 介绍)

8.idea创建maven项目(使用Log4j日志记录框架Log4j 介绍) 在 IntelliJ IDEA 的 Maven 项目中引入了 Log4j&#xff0c;并配置了日志同时输出到控制台和文件。 Log4j 提供了灵活的日志配置选项&#xff0c;可以根据项目需求调整日志级别、输出目标和格式。 1. 创建 Maven 项目 …

【和春笋一起学C++】函数——C++的编程模块

目录 1. 原型句法 2. 函数分类 3. 函数参数之按值传递 4. 数组作为函数参数 在C中&#xff0c;要使用函数&#xff0c;必须要有这三个方面&#xff1a; 函数原型&#xff0c;函数原型描述了函数到编译器的接口&#xff0c;函数原型一般放在include文件中。函数原型告诉编译…

深挖Java基础之:认识Java(创立空间/先导:Java认识)

今天我要介绍的是在Java中对Java的一些基本语法的认识与他们的运用&#xff0c;以及拟举例子说明和运用场景&#xff0c;优势和劣势&#xff0c; 注&#xff1a;本篇文章是对Java的一些基本的&#xff0c;简单的代码块的一些内容&#xff0c;后续会讲解在Java中的变量类型&…

Python+Selenium+Pytest+Allure PO模式UI自动化框架

一、框架结构 allure-report&#xff1a;测试报告base&#xff1a;定位元素封装data&#xff1a;数据log&#xff1a;日志文件page&#xff1a;页面封装文件夹report&#xff1a;缓存报告testcases&#xff1a;测试用例层utils&#xff1a;工具类run.py&#xff1a;执行文件 二…

博物馆除湿控湿保卫战:M-5J1R 电解除湿科技如何重塑文物守护的未来

在卢浮宫幽深的长廊里&#xff0c;达芬奇的《蒙娜丽莎》正经历着一场看不见的战争——不是来自时间的侵蚀&#xff0c;而是空气中无形的水分子。每一件文物都在与湿度进行着无声的抗争&#xff0c;这场抗争关乎人类文明的延续。湿度&#xff0c;这个看不见的文物杀手&#xff0…

【嘉立创EDA】如何找到曲线和直线的交点,或找到弧线和直线的交点

文章路标👉 :one: 文章解决问题:two: 主题内容:three: 参考方法be end..1️⃣ 文章解决问题 操作环境:嘉立创EDA专业版 V2.2.38 本文使用嘉立创EDA,描述如何快速找到曲线和直线交点的方法,这里的曲线包括了弧线等。本文将此过程记录,以供有需要的读者参考。 2️⃣ 主题…

大语言模型能否替代心理治疗师的深度拓展研究:fou

大语言模型能否替代心理治疗师的深度拓展研究 在科技初创企业和研究领域,大型语言模型(LLMs)用于替代心理健康服务提供者的应用备受关注。但研究人员通过对主要医疗机构治疗指南的梳理回顾,并对当前 LLMs(如 gpt-4o)进行实验评估后发现,LLMs 存在对心理疾病患者表达污名…

【linux】Chrony服务器

简介 1.1 时间的重要性 由于 IT 系统中&#xff0c;准确的计时非常重要&#xff0c;有很多种原因需要准确计时&#xff1a; 在网络传输中&#xff0c;数据包括和日志需要准确的时间戳 各种应用程序中&#xff0c;如订单信息&#xff0c;交易信息等 都需要准确的时间戳 1.2 时区…

mysql查看哪些表的自增id已超过某个值

场景 想看哪些表数据比较大&#xff0c;如果用count 比较慢&#xff0c;同时表设计如果是自增&#xff0c;有没有办法一次查出自增id已超过某值的所有表呢。 方法 SELECT AUTO_INCREMENT,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA 库名 AND AUTO_INCRE…

SiamMask原理详解:从SiamFC到SiamRPN++,再到多任务分支设计

SiamMask原理详解&#xff1a;从SiamFC到SiamRPN&#xff0c;再到多任务分支设计 一、引言二、SiamFC&#xff1a;目标跟踪的奠基者1. SiamFC的结构2. SiamFC的局限性 三、SiamRPN&#xff1a;引入Anchor机制的改进1. SiamRPN的创新2. SiamRPN的进一步优化 四、SiamMask&#x…

SpringBoot终极形态:AI生成带OAuth2鉴权的微服务模块(节省20人日)

在数字化转型的浪潮中,开发效率和质量是企业竞争力的关键要素。飞算 JavaAI 作为一款创新的 AI 工具,能在 Spring Boot 开发中,自动生成完整微服务模块,极大提升开发效率。下面,我们就详细介绍如何借助飞算 JavaAI,实现 Spring Boot 微服务模块的自动化生成。 飞算 JavaAI 简介…

Spring缓存注解深度实战:3大核心注解解锁高并发系统性能优化‌

引言&#xff1a;缓存——高并发系统的“性能加速器”‌ 在互联网应用中&#xff0c;数据库查询往往是性能瓶颈的核心。当每秒数千次的请求直接冲击数据库时&#xff0c;系统响应速度会急剧下降&#xff0c;甚至引发宕机风险。‌缓存技术‌应运而生&#xff0c;成为解决这一痛…

CSS元素动画篇:基于当前位置的变换动画(二)

基于当前位置的变换动画&#xff08;二&#xff09; 前言旋转效果类元素动画摇摆动画效果效果预览代码实现 摇晃动画效果效果预览代码实现 螺旋旋转效果预览代码实现 结语 前言 CSS元素动画一般分为两种&#xff1a;一种是元素基于当前位置的变换动画&#xff0c;通过不明显的…

Qt/C++开发监控GB28181系统/设备注册/设备注销/密码认证/心跳保活/校时

一、前言 根据gb28181协议文档&#xff0c;第一步就是需要实现设备的注册&#xff0c;和onvif不同&#xff0c;gb是反过来的&#xff0c;设备端主动连接服务端&#xff0c;而onvif是服务端主动发出搜索&#xff0c;设备被动应答&#xff0c;包括后续的交互几乎都是被动应答&am…

MATLAB 中的图形绘制

一、线图 plot 函数用来创建x和y值的简单线图。 x 0 : 0.05 : 30; %从0到30&#xff0c;每隔0.05取一次值 y sin(x); plot(x,y,LineWidth,2) %若&#xff08;x&#xff0c;y&#xff0c;LineWidth&#xff0c;2&#xff09;可变粗 xlabel("横轴标题") ylab…