em算法的代码
时间: 2023-08-06 10:26:25 浏览: 58
EM算法是一种迭代算法,其代码实现如下:
1. 初始化模型参数,如隐变量的先验概率、分布的参数等。
2. E步骤:计算当前模型下每个数据点属于每个隐变量的概率。
3. M步骤:根据E步骤计算出的隐变量的概率,更新模型参数。
4. 重复第2步和第3步,直到收敛。
下面是一个简单的EM算法的代码示例,以高斯混合模型为例:
```
import numpy as np
from scipy.stats import multivariate_normal
class GMM:
def __init__(self, k=2, max_iter=100, tol=1e-4):
self.k = k # 高斯分布的数量
self.max_iter = max_iter # 最大迭代次数
self.tol = tol # 收敛阈值
self.alpha = np.ones(k) / k # 隐变量的先验概率
self.mu = None # 高斯分布的均值
self.sigma = None # 高斯分布的协方差矩阵
def fit(self, X):
n, d = X.shape
self.mu = X[np.random.choice(n, self.k, replace=False)]
self.sigma = np.tile(np.identity(d), (self.k, 1, 1))
log_likelihood = -np.inf
for _ in range(self.max_iter):
# E步骤
gamma = np.zeros((n, self.k))
for i in range(self.k):
gamma[:, i] = self.alpha[i] * multivariate_normal.pdf(X, mean=self.mu[i], cov=self.sigma[i])
gamma /= gamma.sum(axis=1, keepdims=True)
# M步骤
Nk = gamma.sum(axis=0)
self.alpha = Nk / n
self.mu = gamma.T.dot(X) / Nk[:, np.newaxis]
for i in range(self.k):
diff = X - self.mu[i]
self.sigma[i] = (diff.T * gamma[:, i]).dot(diff) / Nk[i]
# 计算对数似然
new_log_likelihood = np.sum(np.log(gamma.dot(self.alpha)))
if np.abs(new_log_likelihood - log_likelihood) < self.tol:
break
log_likelihood = new_log_likelihood
```
其中,`X`是输入的数据矩阵,`k`是高斯分布的数量,`max_iter`是最大迭代次数,`tol`是收敛阈值,`alpha`、`mu`和`sigma`分别是隐变量的先验概率、高斯分布的均值和协方差矩阵。在`fit`函数中,首先随机初始化`mu`,然后进行E步骤和M步骤,直到对数似然收敛或达到最大迭代次数为止。