0

我試圖在數據集data = [[x,y],...上實現期望最大化算法(高斯混合模型)... ]。我正在使用mv_norm.pdf(data, mean,cov)函數來計算羣集責任。但COV的後6-7次迭代計算協方差(COV矩陣)的新值之後,COV矩陣是變奇異即行列式爲0(非常小的值),並且因此它給錯誤期望最大化算法(高斯混合模型):ValueError:輸入矩陣必須是正半定的

ValueError: the input matrix must be positive semidefinite

raise np.linalg.LinAlgError('singular matrix')

有人可以爲此提出任何解決方案嗎?

#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

Can someone suggest any solution for this?

的問題是你的數據位於維數嚴格小於輸入數據的某個流形。換句話說,例如,您的數據位於一個圓上,而您有三維數據。因此,當您的方法嘗試估計適合您的數據的三維橢球(協方差矩陣)時,它會失敗,因爲最優的橢球是二維橢圓(第三維爲0)。

如何解決?您將需要一些正則化您的協方差估計量。有很多種可能的解決方案,所有以M一步,沒有式步驟,問題是計算協方差:

  • 簡單的解決方案,而不是做這樣的事情cov = np.cov(X)添加一些正則項,像cov = np.cov(X) + eps * np.identity(X.shape[1])eps
  • 使用更好的估計器,如LedoitWolf estimator from scikit-learn

Initially, I've passed [[3,0],[0,3]] for each cluster covariance since expected number of clusters is 3.

這是沒有意義的,協方差矩陣值無關與集羣的數量。你可以用任何或多或少的合理的東西來初始化它。

相關問題