Python EM算法的实现
EM算法(Expectation-Maximization algorithm)是一种迭代求解极大似然估计或极大后验概率估计的算法,常用于含有隐变量的概率模型参数的最大似然估计或极大后验概率估计。它是一种迭代算法,每次迭代分两步:期望步骤和最大化步骤。期望步骤求期望得到后验概率分布,最大化步骤求能最大化期望似然函数的模型参数,然后进入下一轮迭代。
下面介绍Python实现EM算法的完整攻略:
1. 准备数据
首先需要有一组待处理的数据,以Gaussian Mixture Model(GMM)为例,我们可以生成一个模拟数据集,代码示例如下:
import numpy as np
import matplotlib.pyplot as plt
# 产生数据
mean = [[1, 1], [-1, -1], [1, -1]]
cov = [np.eye(2), np.eye(2), np.eye(2)]
n_samples = 500
n_clusters = 3
np.random.seed(0)
X = np.vstack([
np.random.multivariate_normal(mean[i], cov[i], n_samples)
for i in range(n_clusters)
])
2. 初始化参数
开始EM算法之前需要初始化一些参数,包括高斯分布的个数、权重、均值和方差等。
# 初始化参数,这里假设GMM中有3个高斯分布
n_components = 3
weights = np.zeros(n_components)
means = np.zeros((n_components, 2))
covariances = np.zeros((n_components, 2, 2))
# 初始化权重为1/n_components,均值和方差从数据中随机选择
for k in range(n_components):
weights[k] = 1.0 / n_components
means[k] = X[np.random.choice(range(len(X)))]
covariances[k] = np.cov(X, rowvar=False)
3. 迭代求解
在迭代过程中,每次需要进行两步,即期望步骤和最大化步骤。其中期望步骤用来估计隐变量(即数据点属于哪个高斯分布),最大化步骤用来更新高斯分布的参数。
3.1 期望步骤
在第t次迭代时,对于每个样本i,计算其属于不同高斯分布的后验概率,并将其保存在posterior列表中。
def _e_step(X, weights, means, covariances):
n_samples, n_features = X.shape
n_components = len(weights)
# 计算后验概率
posterior = np.zeros((n_samples, n_components))
for k in range(n_components):
likelihood = _gaussian_distribution(X, means[k], covariances[k])
posterior[:, k] = weights[k] * likelihood
# 归一化
normalization = np.sum(posterior, axis=1)[:, np.newaxis]
posterior /= normalization
return posterior
3.2 最大化步骤
在第t次迭代时,根据每个样本i属于不同高斯分布的后验概率,更新每个高斯分布的权重、均值和方差。
def _m_step(X, posterior):
n_samples, n_features = X.shape
n_components = posterior.shape[1]
# 权重的更新
weights = np.mean(posterior, axis=0)
# 均值的更新
means = np.zeros((n_components, n_features))
for k in range(n_components):
means[k] = np.average(X, axis=0, weights=posterior[:, k])
# 方差的更新
covariances = np.zeros((n_components, n_features, n_features))
for k in range(n_components):
diff = X - means[k]
covariances[k] = np.dot((posterior[:, k] * diff.T), diff) / weights[k]
return weights, means, covariances
3.3 迭代实现
将期望步骤和最大化步骤组合起来,实现EM算法的迭代过程。
def expectation_maximization(X, n_components, n_iterations=50):
weights, means, covariances = _initialize_parameters(X, n_components)
for i in range(n_iterations):
posterior = _e_step(X, weights, means, covariances)
weights, means, covariances = _m_step(X, posterior)
return weights, means, covariances
4. 模型评估
使用训练集训练出GMM模型之后,可以使用模型对新的数据进行分类,同时还可以计算模型的似然值和BIC/AIC等指标来评估模型的拟合程度。
这里给出一个简单的示例,使用生成的数据集和训练出的模型,分类新的数据点并绘制出不同高斯分布的轮廓线和质心。
def plot_results(X, weights, means, covariances):
plt.figure(figsize=(10, 5))
plt.scatter(X[:, 0], X[:, 1], s=10, alpha=0.5)
for k in range(len(weights)):
plot_gaussian_ellipse(means[k], covariances[k], alpha=0.5)
plt.scatter(means[k][0], means[k][1], s=50, c='r')
plt.xlim([-4, 4])
plt.ylim([-4, 4])
plt.show()
w, m, c = expectation_maximization(X, n_components=3, n_iterations=50)
plot_results(X, w, means, covariances)
5. 总结
这篇攻略介绍了Python实现EM算法的完整过程,包括准备数据、初始化参数、迭代求解和模型评估。同时给出了两个示例来演示如何使用实现的算法。通过学习本文,可以掌握EM算法的理论和实现方法,以及如何在实际应用中应用EM算法来解决问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python em算法的实现 - Python技术站