期望最大化算法(高斯混合模型):ValueError:输入矩阵必须是半正的

时间:2016-09-30 06:04:46

标签: python-3.x machine-learning covariance gaussian expectation-maximization

我正在尝试在数据集data = [[x,y],...]上实现期望最大化算法(高斯混合模型)。我正在使用mv_norm.pdf(data, mean,cov)函数来计算集群职责。但是在经过6-7次迭代后计算协方差(cov矩阵)的新值后,cov矩阵变得单一,即cov的行列式为0(非常小的值),因此它给出了错误

  

ValueError:输入矩阵必须是半正的

  

提高np.linalg.LinAlgError('奇异矩阵')

有人可以为此建议任何解决方案吗?

#E-step: Compute cluster responsibilities, given cluster parameters
def calculate_cluster_responsibility(data,centroids,cov_m):
    pdfmain=[[] for i in range(0,len(data))]
    for i in range(0,len(data)):
        sum1=0
        pdfeach=[[] for m in range(0,len(centroids))]
        pdfeach[0]=1/3.*mv_norm.pdf(data[i], mean=centroids[0],cov=[[cov_m[0][0][0],cov_m[0][0][1]],[cov_m[0][1][0],cov_m[0][1][1]]])
        pdfeach[1]=1/3.*mv_norm.pdf(data[i], mean=centroids[1],cov=[[cov_m[1][0][0],cov_m[1][0][1]],[cov_m[1][1][0],cov_m[0][1][1]]])
        pdfeach[2]=1/3.*mv_norm.pdf(data[i], mean=centroids[2],cov=[[cov_m[2][0][0],cov_m[2][0][1]],[cov_m[2][1][0],cov_m[2][1][1]]])
        sum1+=pdfeach[0]+pdfeach[1]+pdfeach[2]
        pdfeach[:] = [x / sum1 for x in pdfeach]
        pdfmain[i]=pdfeach

    global old_pdfmain
    if old_pdfmain==pdfmain:
        return
    old_pdfmain=copy.deepcopy(pdfmain)
    softcounts=[sum(i) for i in zip(*pdfmain)]
    calculate_cluster_weights(data,centroids,pdfmain,soft counts)

最初,我已经为每个群集协方差传递了[[3,0],[0,3]],因为预期的簇数是3。

1 个答案:

答案 0 :(得分:1)

  

有人可以为此建议任何解决方案吗?

问题是您的数据位于严格小于输入数据的某些维度中。换句话说,例如,您的数据位于圆上,而您有3维数据。因此,当您的方法尝试估计适合您的数据的三维椭球(协方差矩阵)时,它会失败,因为最优的椭圆是二维椭圆(第三维是0)。

如何解决?您需要协方差估计的一些正则化。有很多可能的解决方案,都在M步骤,而不是E步骤,问题在于计算协方差:

  • 简单的解决方案,而不是像cov = np.cov(X)那样添加一些正则化术语,例如cov = np.cov(X) + eps * np.identity(X.shape[1])eps
  • 使用像LedoitWolf estimator from scikit-learn这样的更好的估算器。
  

最初,我已经为每个群集协方差传递[[3,0],[0,3]],因为预期的群集数量是3。

这没有意义,协方差矩阵值与簇的数量无关。你可以用任何或多或少合理的东西来初始化它。