2015-07-01 4 views
6

Я пытаюсь использовать KernelPCA для уменьшения размерности набора данных до 2D (как для целей визуализации, так и для дальнейшего анализа данных).scikit KernelPCA неустойчивые результаты

Я экспериментировал вычисление KernelPCA с помощью RBF ядра при различных значениях гаммы, но результат неустойчив:

anim

(каждый кадр представляет собой слегка другое значение гаммы, где гамма непрерывно изменяется от 0 до 1)

Похоже, что это не детерминировано.

Есть ли способ стабилизировать его/сделать его детерминированным?

Код, используемый для создания преобразованных данных:

def pca(X, gamma1): 
    kpca = KernelPCA(kernel="rbf", fit_inverse_transform=True, gamma=gamma1) 
    X_kpca = kpca.fit_transform(X) 
    #X_back = kpca.inverse_transform(X_kpca) 
    return X_kpca 

ответ

1

Так что ... Я не могу дать вам окончательный ответ на то, почему KernelPCA не является детерминированным. Поведение напоминает различия, которые я наблюдал между результатами PCA и RandomizedPCA. PCA является детерминированным, но RandomizedPCA не является, и иногда собственные векторы переворачиваются по знаку относительно собственных векторов PCA.

Это приводит меня к моей смутной идее о том, как вы можете получить более детерминированные результаты .... может быть. Используйте RBFSampler с фиксированным семенем:

def pca(X, gamma1): 
    kernvals = RBFSampler(gamma=gamma1, random_state=0).fit_transform(X) 
    kpca = PCA().fit_transform(X) 
    X_kpca = kpca.fit_transform(X) 
    return X_kpca 
3

KernelPCA должен быть детерминированным и непрерывно развиваться с гаммой.
Он отличается от RBFSampler, который имеет встроенную случайность, чтобы обеспечить эффективное (более масштабируемое) приближение ядра RBF.

Однако то, что может измениться в KernelPCA является порядком основных компонентов: в scikit учиться они будут возвращены сортируются в порядке убывания собственных значений, так что если у вас есть 2 собственных близкие друг к другу может быть, что порядок изменяется с гаммой.

Мое предположение (из gif) состоит в том, что это то, что происходит здесь: оси, вдоль которых вы рисуете, не постоянны, поэтому ваши данные, кажется, прыгают.

Не могли бы вы предоставить код, который вы использовали для создания gif?

Я предполагаю, что это график точек данных по двум первым основным компонентам, но это поможет увидеть, как вы его создали.

Вы можете попытаться дополнительно проверить его, посмотрев на значения kpca.alphas_ (собственные векторы) для каждого значения гамма.

Надеюсь, что это имеет смысл.

EDIT: Как вы отметили это выглядит как точки отражаются от оси, наиболее вероятным объяснением является то, что один из собственных векторов переворачивает знак (заметьте, это не влияет на собственное).

Я поставил a simple gist, чтобы воспроизвести проблему (для ее запуска понадобится ноутбук Jupyter). При изменении значения гаммы вы можете видеть переключение знака.

В качестве дополнения обратите внимание, что такое несоответствие происходит только потому, что вы подходят несколько раз объект KernelPCA несколько раз. После того, как вы определились с определенным значением гаммы, и вы подходите kpca, как только вы сможете вызвать трансляцию несколько раз и получить согласованные результаты. Для классического PCA the docs упоминанием, что:

Благодаря реализации тонкостей сингулярного разложения (SVD), который используется в этой реализации, работает нужным дважды на одной и той же матрицы может привести к основным компонентам с признаками перевернутых (изменение направления). По этой причине важно всегда использовать один и тот же объект-оценщик для последовательного преобразования данных.

Я не знаю о поведении одного объекта KernelPCA, который вы бы поместили несколько раз (я не нашел в документах ничего важного).

Это не относится к вашему делу, хотя вам необходимо установить объект с несколькими значениями гаммы.

+0

Да, участок является первым двумя основными компонентами – fferri

+1

Хорошо. Вы видите, как порядок компонентов может повлиять на ваш сюжет? Скажите, что ваши первые 2 компонента - e1 и e2, с соответствующими собственными значениями a1 и a2. Для гамма = 0,5, a1> a2. Таким образом, KernelPCA возвращает собственные векторы в порядке e1, e2, e3 ... Для гамма = 0,6, a2> a1. Теперь вы получаете e2, e1, e3 ... и ваши оси на графике меняются местами. – ldirer

+0

Похоже, что знак сальто собственных значений. Если подмена осей (x с y), я должен наблюдать точки * транспонировать *. Вместо этого точки * отражают * по x или y. Вы не согласны? – fferri

Смежные вопросы