利用MCMC方法产生平稳的马尔科夫链

news/2025/9/22 9:42:55/文章来源:https://www.cnblogs.com/y54y5666/p/19104580

马尔科夫链蒙特卡洛(MCMC)方法是一种通过构建平稳马尔科夫链来从复杂概率分布中采样的强大技术。

% 利用MCMC方法产生平稳的马尔科夫链
clear; clc; close all;%% 1. 参数设置
fprintf('设置MCMC参数...\n');% MCMC参数
n_samples = 10000;      % 总样本数
burn_in = 2000;         % 预热期样本数
thin = 5;               % 稀释间隔(每thin个样本取1个)% 目标分布参数(多元正态分布)
mu = [1, 2];            % 均值向量
sigma = [1, 0.8; 0.8, 1]; % 协方差矩阵% 建议分布参数(正态分布)
proposal_std = [0.5, 0.5]; % 建议分布的标准差%% 2. 初始化马尔科夫链
fprintf('初始化马尔科夫链...\n');% 初始状态
current_state = [0, 0]; % 初始点% 存储链
chain = zeros(n_samples, length(mu));
acceptance = zeros(n_samples, 1); % 记录是否接受%% 3. 定义目标分布和建议分布
fprintf('定义概率分布函数...\n');% 目标分布(多元正态分布)
target_pdf = @(x) mvnpdf(x, mu, sigma);% 建议分布(对称的,因此Metropolis-Hastings比率为1)
proposal_pdf = @(x, y) prod(normpdf(x, y, proposal_std));% 建议分布采样函数
proposal_rnd = @(y) y + normrnd(0, proposal_std);%% 4. Metropolis-Hastings算法
fprintf('运行Metropolis-Hastings算法...\n');for i = 1:n_samples% 从建议分布中生成候选点candidate = proposal_rnd(current_state);% 计算接受概率acceptance_ratio = target_pdf(candidate) / target_pdf(current_state);% 由于建议分布是对称的,q(candidate|current)/q(current|candidate)=1% 对于非对称建议分布,需要乘以建议分布比率% 决定是否接受候选点if rand() < min(1, acceptance_ratio)current_state = candidate;acceptance(i) = 1;end% 存储当前状态chain(i, :) = current_state;% 显示进度if mod(i, 1000) == 0fprintf('已完成 %d/%d 次迭代\n', i, n_samples);end
end% 计算接受率
acceptance_rate = mean(acceptance) * 100;
fprintf('接受率: %.2f%%\n', acceptance_rate);%% 5. 后处理:去除预热期和稀释
fprintf('处理后处理...\n');% 去除预热期
chain = chain(burn_in+1:end, :);
acceptance = acceptance(burn_in+1:end);% 稀释
chain = chain(1:thin:end, :);
acceptance = acceptance(1:thin:end);fprintf('处理后样本数: %d\n', size(chain, 1));%% 6. 收敛诊断
fprintf('进行收敛诊断...\n');% 绘制轨迹图
figure;
subplot(2, 2, 1);
plot(chain(:, 1));
xlabel('迭代次数');
ylabel('x_1');
title('马尔科夫链轨迹 (x_1)');
grid on;subplot(2, 2, 2);
plot(chain(:, 2));
xlabel('迭代次数');
ylabel('x_2');
title('马尔科夫链轨迹 (x_2)');
grid on;% 绘制自相关函数
subplot(2, 2, 3);
autocorr(chain(:, 1), 50);
title('x_1的自相关函数');subplot(2, 2, 4);
autocorr(chain(:, 2), 50);
title('x_2的自相关函数');% 计算Gelman-Rubin统计量(需要多条链)
fprintf('计算Gelman-Rubin统计量...\n');
n_chains = 4; % 多条链的数量
gr_stats = gelman_rubin(chain, n_chains, mu, sigma, proposal_std);
fprintf('Gelman-Rubin统计量: x_1=%.4f, x_2=%.4f\n', gr_stats(1), gr_stats(2));%% 7. 评估采样质量
fprintf('评估采样质量...\n');% 绘制样本分布与目标分布的比较
figure;% 创建网格用于绘制目标分布
x1 = linspace(min(chain(:,1))-1, max(chain(:,1))+1, 100);
x2 = linspace(min(chain(:,2))-1, max(chain(:,2))+1, 100);
[X1, X2] = meshgrid(x1, x2);
X = [X1(:), X2(:)];% 计算目标分布
Z = mvnpdf(X, mu, sigma);
Z = reshape(Z, size(X1));% 绘制等高线图
subplot(2, 2, 1);
contour(X1, X2, Z, 20);
hold on;
plot(chain(:,1), chain(:,2), '.', 'MarkerSize', 2, 'Color', [0.7, 0.7, 0.7]);
xlabel('x_1');
ylabel('x_2');
title('样本与目标分布');
colorbar;% 绘制边际分布
subplot(2, 2, 2);
histogram(chain(:,1), 50, 'Normalization', 'pdf');
hold on;
plot(x1, normpdf(x1, mu(1), sqrt(sigma(1,1))), 'r', 'LineWidth', 2);
xlabel('x_1');
ylabel('密度');
title('x_1的边际分布');
legend('样本', '真实分布');subplot(2, 2, 3);
histogram(chain(:,2), 50, 'Normalization', 'pdf');
hold on;
plot(x2, normpdf(x2, mu(2), sqrt(sigma(2,2))), 'r', 'LineWidth', 2);
xlabel('x_2');
ylabel('密度');
title('x_2的边际分布');
legend('样本', '真实分布');% 计算样本均值和协方差
sample_mean = mean(chain);
sample_cov = cov(chain);fprintf('真实均值: [%.4f, %.4f]\n', mu(1), mu(2));
fprintf('样本均值: [%.4f, %.4f]\n', sample_mean(1), sample_mean(2));
fprintf('真实协方差矩阵: [%.4f, %.4f; %.4f, %.4f]\n', ...sigma(1,1), sigma(1,2), sigma(2,1), sigma(2,2));
fprintf('样本协方差矩阵: [%.4f, %.4f; %.4f, %.4f]\n', ...sample_cov(1,1), sample_cov(1,2), sample_cov(2,1), sample_cov(2,2));%% 8. 辅助函数定义function gr_stats = gelman_rubin(chain, n_chains, mu, sigma, proposal_std)% 计算Gelman-Rubin统计量% 将现有链分割成多个部分,模拟多条链n_samples = size(chain, 1);chain_length = floor(n_samples / n_chains);chains = cell(n_chains, 1);% 生成多条链for i = 1:n_chains% 使用不同的初始值initial_state = normrnd(0, 1, 1, 2);% 运行MCMCchain_i = mcmc_chain(chain_length, initial_state, mu, sigma, proposal_std);chains{i} = chain_i;end% 计算Gelman-Rubin统计量% 对于每个参数gr_stats = zeros(1, 2);for param = 1:2% 计算链内方差W = 0;for i = 1:n_chainsW = W + var(chains{i}(:, param));endW = W / n_chains;% 计算链均值chain_means = zeros(n_chains, 1);for i = 1:n_chainschain_means(i) = mean(chains{i}(:, param));end% 计算链间方差B = chain_length * var(chain_means);% 计算估计方差var_estimate = (chain_length - 1)/chain_length * W + 1/chain_length * B;% 计算Gelman-Rubin统计量gr_stats(param) = sqrt(var_estimate / W);end
endfunction chain = mcmc_chain(n_samples, initial_state, mu, sigma, proposal_std)% 运行MCMC生成一条链target_pdf = @(x) mvnpdf(x, mu, sigma);proposal_rnd = @(y) y + normrnd(0, proposal_std);current_state = initial_state;chain = zeros(n_samples, length(mu));for i = 1:n_samples% 从建议分布中生成候选点candidate = proposal_rnd(current_state);% 计算接受概率acceptance_ratio = target_pdf(candidate) / target_pdf(current_state);% 决定是否接受候选点if rand() < min(1, acceptance_ratio)current_state = candidate;end% 存储当前状态chain(i, :) = current_state;end
end%% 9. 自适应MCMC算法(可选)
fprintf('尝试自适应MCMC算法...\n');% 自适应MCMC参数
n_adaptive = 5000;          % 自适应阶段样本数
initial_std = [1.0, 1.0];   % 初始建议分布标准差
target_acceptance = 0.234;  % 目标接受率(最优值)% 初始化
adaptive_chain = zeros(n_adaptive, length(mu));
adaptive_acceptance = zeros(n_adaptive, 1);
current_std = initial_std;
current_state = [0, 0];% 运行自适应MCMC
for i = 1:n_adaptive% 从建议分布中生成候选点candidate = current_state + normrnd(0, current_std);% 计算接受概率acceptance_ratio = target_pdf(candidate) / target_pdf(current_state);% 决定是否接受候选点if rand() < min(1, acceptance_ratio)current_state = candidate;adaptive_acceptance(i) = 1;end% 存储当前状态adaptive_chain(i, :) = current_state;% 自适应调整建议分布标准差if mod(i, 100) == 0current_acceptance = mean(adaptive_acceptance(i-99:i));% 根据接受率调整标准差if current_acceptance > target_acceptancecurrent_std = current_std * 1.1; % 增加探索elsecurrent_std = current_std * 0.9; % 减少探索endend
end% 绘制自适应过程
figure;
subplot(2, 1, 1);
plot(adaptive_chain(:,1));
xlabel('迭代次数');
ylabel('x_1');
title('自适应MCMC轨迹 (x_1)');
grid on;subplot(2, 1, 2);
plot(adaptive_chain(:,2));
xlabel('迭代次数');
ylabel('x_2');
title('自适应MCMC轨迹 (x_2)');
grid on;%% 10. 不同建议分布的比较(可选)
fprintf('比较不同建议分布...\n');% 定义不同的建议分布标准差
proposal_stds = {[0.1, 0.1], [0.5, 0.5], [2.0, 2.0]};
n_comparison = 3000;
colors = ['r', 'g', 'b'];figure;
hold on;for i = 1:length(proposal_stds)% 运行MCMCchain_comp = mcmc_chain(n_comparison, [0, 0], mu, sigma, proposal_stds{i});% 计算接受率acceptance_ratio = sum(diff(chain_comp(:,1)) ~= 0) / (n_comparison - 1);% 绘制轨迹plot(chain_comp(:,1), chain_comp(:,2), '.', 'Color', colors(i), 'MarkerSize', 4);fprintf('建议分布标准差 [%.1f, %.1f] - 接受率: %.2f%%\n', ...proposal_stds{i}(1), proposal_stds{i}(2), acceptance_ratio*100);
end% 绘制目标分布等高线
contour(X1, X2, Z, 10, 'k', 'LineWidth', 1.5);
xlabel('x_1');
ylabel('x_2');
title('不同建议分布的比较');
legend('std=0.1', 'std=0.5', 'std=2.0', '目标分布');
grid on;
hold off;%% 11. 输出总结
fprintf('\n===== MCMC模拟总结 =====\n');
fprintf('目标分布: 二元正态分布, μ=[%.2f, %.2f], Σ=[%.2f, %.2f; %.2f, %.2f]\n', ...mu(1), mu(2), sigma(1,1), sigma(1,2), sigma(2,1), sigma(2,2));
fprintf('建议分布: 正态分布, std=[%.2f, %.2f]\n', proposal_std(1), proposal_std(2));
fprintf('总样本数: %d (预热期: %d, 稀释间隔: %d)\n', n_samples, burn_in, thin);
fprintf('最终样本数: %d\n', size(chain, 1));
fprintf('接受率: %.2f%%\n', acceptance_rate);
fprintf('Gelman-Rubin统计量: x_1=%.4f, x_2=%.4f\n', gr_stats(1), gr_stats(2));
fprintf('样本均值: [%.4f, %.4f]\n', sample_mean(1), sample_mean(2));
fprintf('样本协方差: [%.4f, %.4f; %.4f, %.4f]\n', ...sample_cov(1,1), sample_cov(1,2), sample_cov(2,1), sample_cov(2,2));

程序说明

这个MATLAB程序展示了如何使用MCMC方法(特别是Metropolis-Hastings算法)产生平稳的马尔科夫链,包括以下主要内容:

1. MCMC参数设置

  • 定义样本数量、预热期和稀释间隔
  • 设置目标分布(多元正态分布)的参数
  • 配置建议分布(正态分布)的参数

2. Metropolis-Hastings算法实现

  • 初始化马尔科夫链
  • 定义目标分布和建议分布函数
  • 实现Metropolis-Hastings算法的核心步骤:
    1. 从建议分布生成候选点
    2. 计算接受概率
    3. 根据接受概率决定是否接受候选点
    4. 更新链状态

3. 后处理与收敛诊断

  • 去除预热期样本
  • 应用稀释以减少自相关性
  • 绘制链轨迹和自相关函数
  • 计算Gelman-Rubin统计量评估收敛性

4. 采样质量评估

  • 比较样本分布与目标分布
  • 计算样本均值和协方差矩阵
  • 评估与真实参数的接近程度

5. 高级功能

  • 实现自适应MCMC算法,动态调整建议分布参数
  • 比较不同建议分布对采样效率的影响
  • 提供完整的性能评估和总结报告

参考代码 利用MCMC(马尔科夫蒙特卡洛)方法,产生平稳的马尔科夫链 www.youwenfan.com/contentcnh/64018.html

关键概念

Metropolis-Hastings算法

Metropolis-Hastings算法是MCMC方法中最常用的算法之一,其核心步骤如下:

  1. 从建议分布\(q(x'|x_t)\)中抽取候选样本\(x'\)
  2. 计算接受概率:\(\alpha = \min\left(1, \frac{p(x')q(x_t|x')}{p(x_t)q(x'|x_t)}\right)\)
  3. 以概率\(\alpha\)接受候选样本,设置\(x_{t+1} = x'\);否则\(x_{t+1} = x_t\)

平稳分布

马尔科夫链的平稳分布是指当链达到稳定状态后,状态的概率分布不再随时间变化。MCMC方法的核心思想是构建一个马尔科夫链,使其平稳分布等于目标分布。

收敛诊断

  • 轨迹图:直观检查链是否达到稳定状态
  • 自相关函数:评估样本之间的相关性
  • Gelman-Rubin统计量:通过比较多条链的方差评估收敛性

使用说明

  1. 修改目标分布参数以适应您的具体问题
  2. 调整建议分布的标准差以优化接受率(理想接受率约为23.4%)
  3. 根据链的混合情况调整预热期和稀释间隔
  4. 使用收敛诊断工具确保链已达到平稳状态

扩展应用

这个MCMC框架可以扩展到各种复杂分布和问题:

  1. 高维分布:处理更高维度的目标分布
  2. 非正态分布:适应各种复杂的概率分布形式
  3. 分层贝叶斯模型:应用于复杂的统计模型
  4. 模型选择:结合贝叶因子进行模型比较
  5. 实时MCMC:实现在线学习和自适应采样

注意事项

  1. 建议分布的选择对MCMC效率至关重要
  2. 预热期长度应足够长,确保链达到平稳状态
  3. 稀释可以减少样本间的自相关性,但会增加计算成本
  4. 对于复杂分布,可能需要使用更先进的MCMC算法(如HMC、NUTS等)

这个实现提供了一个完整的MCMC框架,您可以根据实际需求进行修改和扩展,以应用于各种复杂的概率分布采样问题。

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

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

相关文章

FDS-400 土壤温湿电导率盐分传感器 四合一款 频域法测量

FDS-400 土壤温湿电导率盐分传感器 四合一款 频域法测量产品概述 土壤温度部分是由精密铂电阻和高精度变送器两部分组成。变送器部分由电源模块、温度传感模块、变送模块、温度补偿模块及数据处理模块等组成,彻底解…

接口压测方案

项目名称: 版本号: 编写人: 审核人: 日期:测试目标验证系统在预期用户并发量下的响应时间是否达标 评估系统在峰值负载下的稳定性 识别系统性能瓶颈(CPU、内存、数据库、网络等) 为系统优化提供数据支持 吞吐量…

pc.vivo.com vivo办公套件网页,拼图验证失败的原因

chrome 扩展程序里,找到 Phantom 禁用掉,就能正常登录了!本文来自博客园,作者:imzhi,转载请注明原文链接:https://www.cnblogs.com/imzhi/p/19104572

产业投资集团如何科学选择HR系统?一文详解5大选型维度与主流产品对比

【精选摘要】在多元控参、高度分层的产业投资集团中,如何科学选型HR系统,成为数字化转型的核心议题。本文聚焦集团化管理痛点,系统梳理选型关键维度,详解SAP、Workday、红海云、金蝶、用友五大主流产品在实际业务场…

J-link RTT 助手,串口助手,数据可视化,波形图显示,多多盒子

非常好用的一个软件 J-link RTT 助手:串口助手:下载地址: https://gitee.com/momingchuan/duo-duo-box

No.72 阿里图标库的使用

一、打开官网 https://www.iconfont.cn/ 二. 添加到购物车 三.下载代码,解压四.引用 打开demo_index.html文件

python处理Excel的单机小工具:自动合并相同数据的行, 并同时计算其他列的加和

2025-09-22 场景: 一个表格, 比如有 序号, 姓名, 班级, 考分 几列, 要求: 1. 要按照班级合并, 相同的班级的行合并在一起 2. 序号这一列也同时合并 3. 合并后, 计算每个班级的总考分 原始表:处理后的表:软件交互: 1: 选…

297、瑶瑟怨

297、瑶瑟怨 297、瑶瑟怨 唐●温庭筠 冰簟银床梦不成,碧天如水夜云轻。 雁声远过潇湘去,十二楼中月自明。【现代诗意译】 月光下 铺着清凉竹席的床上 我难以入眠 团圆美梦也做不成了 天空碧蓝如水 飘着几片薄薄夜云一…

极飞科技携手纷享销客CRM实现业务全链条数字化

极飞科技股份有限公司(以下简称“极飞科技”)是全球领先的农业机器人公司,致力于用机器人、人工智能和新能源技术赋能农业。随着业务持续拓展与战略升级,极飞客户面临线索管理分散、多系统数据孤岛等挑战。为进一步…

接私活神器!一个轻量级的 Java 快速开发平台!

X-SpringBoot —— 一个轻量级的 Java 快速开发平台,用于快速构建中小型 API、RESTful API 项目,代码简洁,架构清晰,能快速开发项目并交付(接私活神器)。大家好,我是 Java陈序员。 在日常开发中,无论是企业内部…

第四届能源与动力工程国际学术会议(EPE 2025)

第四届能源与动力工程国际学术会议(EPE 2025) 2025 4th International Conference on Energy and Power Engineering 由大连理工大学主办、中国科学报社支持的第四届能源与动力工程国际学术会议(EPE 2025)将于2025…

第五届电子信息工程与计算机技术国际学术会议(EIECT 2025)

第五届电子信息工程与计算机技术国际学术会议(EIECT 2025) 2025 5th International Conference on Electronic Information Engineering and Computer Technology 随着科学技术的高速发展,计算机技术革新日新月异,…

2025年污染治理与可持续发展国际学术会议(PGSD 2025)

2025年污染治理与可持续发展国际学术会议(PGSD 2025) 2025 International Conference on Pollution Governance and Sustainable Development 由马来西亚理工大学主办的2025年污染治理与可持续发展国际学术会议(PGS…

深入解析:对比:ClickHouse/MySQL/Apache Doris

深入解析:对比:ClickHouse/MySQL/Apache Dorispre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", …

实用指南:揭秘Pixie Dust攻击:利用路由器WPS漏洞离线破解PIN码接入无线网络

实用指南:揭秘Pixie Dust攻击:利用路由器WPS漏洞离线破解PIN码接入无线网络pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

深入解析:2025-09-05 CSS3——盒子模型

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

JDK 25 正式发布,长期支持

JDK 25 是 LTS(长期支持版),至此为止,有 JDK8、JDK11、JDK17、JDK21 和 JDK 25 这四个长期支持版了。 JDK 25 共有 18 个新特性,这篇文章会挑选其中较为重要的一些新特性进行详细介绍 语言特性 基本类型模式匹配(…

2025 年(2026 届)计算机保研记录

925 后发布。经验分享篇。 在写了,925 后发布。作者@Luckyblock,转载请声明出处。

linux驱动制作

linux驱动制作2025-09-22 08:59 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

实用指南:RESTful API:@RequestParam与@PathVariable实战对比

实用指南:RESTful API:@RequestParam与@PathVariable实战对比pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…