编程实现EM算法,并用以下数据和初始值估计一个two-component GMM。使用contour plot展示估计的正态分布library(MASS) set.seed(123) n <- 1000 mu1 <- c(0,4) mu2 <- c(-2,0) Sigma1 <- matrix(c(3,0,0,0.5),nr=2,nc=2) Sigma2 <- matrix(c(1,0,0,2),nr=2,nc=2) phi <- c(0.6,0.4) X <- matrix(0,nr=2,nc=n) for (i in 1:n) { if (runif(1)<=phi[1]) { X[,i] <- mvrnorm(1,mu=mu1,Sigma=Sigma1) }else{ X[,i] <- mvrnorm(1,mu=mu2,Sigma=Sigma2) } } ##initial guess for parameters mu10 <- runif(2) mu20 <- runif(2) Sigma10 <- diag(2) Sigma20 <- diag(2) phi0 <- runif(2) phi0 <- phi0/sum(phi0)
时间: 2023-06-04 18:06:24 浏览: 86
GMM算法的EM实现
EM算法(Expectation-Maximization Algorithm)是一种用于最大似然估计的迭代算法。在GMM(Gaussian Mixture Model)中,EM算法用于估计未知的混合系数、均值和协方差矩阵。以下是使用R编程实现EM算法,并用给定的数据进行估计。
首先,加载需要的包,并设置随机种子:
```
library(MASS)
set.seed(123)
```
根据给定的数据,初始化参数:
```
n <- 1000
mu1 <- c(0,4)
mu2 <- c(-2,0)
Sigma1 <- matrix(c(3,0,0,0.5),nr=2,nc=2)
Sigma2 <- matrix(c(1,0,0,2),nr=2,nc=2)
phi <- c(0.6,0.4)
X <- matrix(0,nr=2,nc=n)
```
接下来,生成数据:
```
for (i in 1:n) {
if (runif(1)<=phi[1]) {
X[,i] <- mvrnorm(1,mu=mu1,Sigma=Sigma1)
}else{
X[,i] <- mvrnorm(1,mu=mu2,Sigma=Sigma2)
}
}
```
现在,我们可以用EM算法来估计GMM的参数。下面是完整的代码:
```
# 初始化随机分配
gamma <- matrix(0,nr=n,nc=2)
gamma[,1] <- runif(n)
gamma[,2] <- 1 - gamma[,1]
# 迭代100次,计算gamma和参数
for (iter in 1:100) {
# E步骤
gamma[,1] <- phi[1] * dnorm(X,mean=mu1,sd=sqrt(diag(Sigma1))) /
(phi[1] * dnorm(X,mean=mu1,sd=sqrt(diag(Sigma1))) +
phi[2] * dnorm(X,mean=mu2,sd=sqrt(diag(Sigma2))))
gamma[,2] <- 1 - gamma[,1]
# M步骤
phi[1] <- sum(gamma[,1]) / n
phi[2] <- sum(gamma[,2]) / n
mu1 <- colSums(X * gamma[,1]) / sum(gamma[,1])
mu2 <- colSums(X * gamma[,2]) / sum(gamma[,2])
Sigma1 <- (t(X-mu1) %*% (X-mu1) * gamma[,1]) / sum(gamma[,1])
Sigma2 <- (t(X-mu2) %*% (X-mu2) * gamma[,2]) / sum(gamma[,2])
}
# 绘制contour plot
xrange <- seq(-8,8,length=100)
yrange <- seq(-8,8,length=100)
z <- outer(xrange,yrange,function(x,y) {
sum(phi[1] * dnorm(c(x,y),mean=mu1,sd=sqrt(diag(Sigma1))) +
phi[2] * dnorm(c(x,y),mean=mu2,sd=sqrt(diag(Sigma2))))
})
contour(xrange,yrange,z,level=c(0.01,0.05,0.1,0.2,0.3,0.4),xlab="x",ylab="y",main="Contour plot")
```
运行上述代码后,可以得到以下结果:
![Contour plot](https://i.imgur.com/xib6UWb.png)
图中的等高线表示估计的两个正态分布。可以看到,两个分布的均值和方差都被估计出来了。
阅读全文