Кластеризация среднего сдвига Python для массива комплексных чисел - PullRequest
0 голосов
/ 03 октября 2018

Я унаследовал некоторый код, который был написан около года назад, поэтому я думаю, тогда он использовал numpy 1.13 (сейчас v1.15.2), scipy 1.00rc (теперь v1.1.0) и sklearn 0.19 (теперь v.0.20.0).

Реализуется LDA * Фишера для уменьшения n -мерное пространство к пространству 1… n -1, которое в результате приводит к массиву комплексных чисел (из-за неточности с плавающей запятой).Этот массив затем подбирается и подается в sklearn.cluster.MeanShift, который немедленно вызывает исключение:

  File "/…/lib/python3.6/site-packages/sklearn/cluster/mean_shift_.py", line 416, in fit
    X = check_array(X)
  File "/…/lib/python3.6/site-packages/sklearn/utils/validation.py", line 531, in check_array
    _ensure_no_complex_data(array)
  File "/…/lib/python3.6/site-packages/sklearn/utils/validation.py", line 354, in _ensure_no_complex_data
    "{}\n".format(array))
ValueError: Complex data not supported

Я все еще изучаю математические детали того, что здесь происходит, но это поражаетмне кажется странным, что этот код был объявлен «работоспособным».

Я что-то здесь упускаю?Произошли ли изменения версии в результате этой регрессии, или есть более фундаментальный недостаток кода?Как бы я решил эту проблему?

1 Ответ

0 голосов
/ 06 октября 2018

В комментариях / чате мы определили, по крайней мере, одну проблему, заключающуюся в том, что числовое разложение собственных чисел

(cov_w + I)^-1 @ cov_b                       (1)

не является реальным, как должно, но возвращает значительные мнимые компоненты.Здесь @ - умножение матриц, cov_w и cov_b - ковариационные матрицы, а I - единичная матрица.Это можно исправить путем вычисления квадратного корня матрицы из (cov_w + I) ^ - 1, назовем его SQ, а затем используем тот факт, что (1) аналогично

SQ @ cov_b @ SQ                              (2)

, следовательно, имеет те же собственные значения иесли V являются собственными векторами (2), то (правые) собственные векторы (1) имеют вид SQ @ V.

Мы получили то, что, поскольку (2) является симметричной матрицей, ее собственное разложение можно вычислитьиспользуя numpy.linalg.eigh, что гарантирует чисто реальные результаты.eigh также может использоваться для вычисления SQ, см. здесь .Обязательно обходите обратное и применяйте eigh непосредственно к cov_w + I или даже cov_w.

...