matlab中的EM算法生成混合高斯分布的代码
时间: 2024-01-04 22:04:28 浏览: 115
以下是MATLAB中使用EM算法生成混合高斯分布的示例代码:
```matlab
% 生成混合高斯分布数据
clear;
close all;
clc;
% 设定参数
N = 500; % 样本个数
K = 3; % 高斯分布个数
mu_true = [0.5 3 -2]; % 真实均值
sigma_true = [1 0.5 0.8]; % 真实标准差
p_true = [0.4 0.3 0.3]; % 真实混合系数
% 生成数据
data = zeros(N, 1);
for i = 1:N
k = randsample(1:K, 1, true, p_true); % 采样高斯分布
data(i) = normrnd(mu_true(k), sigma_true(k)); % 生成数据
end
% 初始化参数
mu = rand(1, K) * range(data) + min(data); % 随机初始化均值
sigma = ones(1, K); % 初始化标准差
p = ones(1, K) / K; % 初始化混合系数
% EM算法
max_iter = 100; % 最大迭代次数
tolerance = 1e-6; % 收敛阈值
log_likelihood = -inf(1, max_iter); % 记录对数似然值
for iter = 1:max_iter
% E步骤
gamma = zeros(N, K); % 后验概率
for k = 1:K
gamma(:, k) = p(k) * normpdf(data, mu(k), sigma(k));
end
gamma = gamma ./ sum(gamma, 2); % 归一化
% M步骤
Nk = sum(gamma, 1); % 每个高斯分布的样本数
mu_new = sum(bsxfun(@times, gamma, data), 1) ./ Nk; % 更新均值
sigma_new = sqrt(sum(bsxfun(@times, gamma, bsxfun(@minus, data, mu_new).^2), 1) ./ Nk); % 更新标准差
p_new = Nk / N; % 更新混合系数
% 计算对数似然值
log_likelihood(iter) = sum(log(sum(bsxfun(@times, gamma, p_new), 2)));
% 判断收敛
if iter > 1 && abs(log_likelihood(iter) - log_likelihood(iter-1)) < tolerance
break;
end
% 更新参数
mu = mu_new;
sigma = sigma_new;
p = p_new;
end
% 绘图
x = linspace(min(data), max(data), 1000);
y_true = zeros(size(x));
y_pred = zeros(size(x));
for k = 1:K
y_true = y_true + p_true(k) * normpdf(x, mu_true(k), sigma_true(k));
y_pred = y_pred + p(k) * normpdf(x, mu(k), sigma(k));
end
figure;
histogram(data, 'Normalization', 'pdf');
hold on;
plot(x, y_true, 'r-', 'LineWidth', 2);
plot(x, y_pred, 'g--', 'LineWidth', 2);
legend('Data', 'True PDF', 'Estimated PDF');
title('Mixture Gaussian Distribution');
```
该代码使用EM算法生成混合高斯分布,并绘制了真实分布和估计分布的比较。其中,E步骤计算后验概率,M步骤更新参数,对数似然值用于判断收敛。可以根据需要调整参数和修改代码。
阅读全文