Я пытаюсь реализовать алгоритм максимизации ожиданий (модель смеси Гаусса) для набора данных data=[[x,y],...]. Я использую функцию mv_norm.pdf(data, mean,cov)
для расчета ответственности кластера. Но после вычисления новых значений ковариации (матрицы cov) после 6-7 итераций матрица 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.