Алгоритм максимизации ожидания (модель смеси Гаусса): ValueError: входная матрица должна быть положительно полуопределенной

Я пытаюсь реализовать алгоритм максимизации ожиданий (модель смеси Гаусса) для набора данных 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.


person Madhura Raut    schedule 30.09.2016    source источник


Ответы (1)


Может ли кто-нибудь предложить какое-либо решение для этого?

Проблема в том, что ваши данные лежат в некотором многообразии размерности, строго меньшей, чем входные данные. Другими словами, например, ваши данные лежат на круге, а у вас есть трехмерные данные. Как следствие, когда ваш метод пытается оценить трехмерный эллипсоид (ковариационную матрицу), который соответствует вашим данным, он терпит неудачу, поскольку оптимальным является двумерный эллипс (третье измерение равно 0).

Как это исправить? Вам понадобится некоторая регуляризация вашей ковариационной оценки. Есть много возможных решений, все на шаге M, а не на шаге E, проблема заключается в вычислении ковариации:

  • Простое решение: вместо того, чтобы делать что-то вроде cov = np.cov(X), добавьте какой-нибудь упорядочивающий термин, например cov = np.cov(X) + eps * np.identity(X.shape[1]) с небольшим eps
  • Используйте более удобный оценщик, например оценщик LedoitWolf от scikit-learn.

Первоначально я передал [[3,0],[0,3]] для каждой ковариации кластеров, поскольку ожидаемое количество кластеров равно 3.

Это не имеет смысла, значения ковариационной матрицы не имеют ничего общего с количеством кластеров. Вы можете инициализировать его чем-нибудь более или менее разумным.

person lejlot    schedule 01.10.2016