Я пытаюсь написать свою собственную функцию для анализа главных компонентов, PCA (конечно, многое уже написано, но я просто заинтересован в том, чтобы реализовать что-то самостоятельно). Основная проблема, с которой я столкнулся, - это этап перекрестной проверки и вычисления прогнозируемой суммы квадратов (PRESS). Неважно, какую перекрестную проверку я использую, речь идет в основном о теории позади, но рассмотрим перекрестную проверку без участия (LOOCV). Из теории я узнал, что для выполнения LOOCV необходимо:
- удалить объект
- масштабировать остальное
- выполнить PCA с некоторым количеством компонентов
- масштабировать удаленный объект в соответствии с параметрами, полученными в (2)
- предсказать объект в соответствии с моделью PCA
- рассчитать ПРЕСС для этого объекта
- повторно выполнить тот же алгоритм для других объектов
- суммировать все значения ПРЕССА
- прибыль
Поскольку я очень новичок в этой области, чтобы быть уверенным, что я прав, я сравниваю результаты с результатами некоторых программ, которые у меня есть (также, чтобы написать код, я следую инструкциям в программном обеспечении). Я получаю полностью те же результаты, вычисляя остаточную сумму квадратов и , но вычисление PRESS является проблемой.
Не могли бы вы сказать мне, правильно ли то, что я реализую на этапе перекрестной проверки:
case 'loocv'
% # n - number of objects
% # p - number of variables
% # vComponents - the number of components used in CV
dataSets = divideData(n,n);
% # it is just a variable responsible for creating datasets for CV
% # (for LOOCV datasets will be equal to [1, 2, 3, ... , n]);'
tempPRESS = zeros(n,vComponents);
for j = 1:n
Xmodel1 = X; % # X - n x p original matrix
Xmodel1(dataSets{j},:) = []; % # delete the object to be predicted
[Xmodel1,Xmodel1shift,Xmodel1div] = skScale(Xmodel1, 'Center', vCenter,
'Scaling', vScaling);
% # scale the data and extract the shift and scaling factor
Xmodel2 = X(dataSets{j},:); % # the object to be predicted
Xmodel2 = bsxfun(@minus,Xmodel2,Xmodel1shift); % # shift and scale the object
Xmodel2 = bsxfun(@rdivide,Xmodel2,Xmodel1div);
[Xscores2,Xloadings2] = myNipals(Xmodel1,0.00000001,vComponents);
% # the way to calculate the scores and loadings
% # Xscores2 - n x vComponents matrix
% # Xloadings2 - vComponents x p matrix
for i = 1:vComponents
tempPRESS(j,i) = sum(sum((Xmodel2* ...
(eye(p) - transpose(Xloadings2(1:i,:))*Xloadings2(1:i,:))).^2));
end
end
PRESS = sum(tempPRESS,1);
В программном обеспечении ( PLS_Toolbox ) это работает так:
for i = 1:vComponents
tempPCA = eye(p) - transpose(Xloadings2(1:i,:))*Xloadings2(1:i,:);
for kk = 1:p
tempRepmat(:,kk) = -(1/tempPCA(kk,kk))*tempPCA(:,kk);
% # this I do not understand
tempRepmat(kk,kk) = -1;
% # here is some normalization that I do not get
end
tempPRESS(j,i) = sum(sum((Xmodel2*tempRepmat).^2));
end
Таким образом, они выполняют некоторую дополнительную нормализацию, используя эту tempRepmat
переменную: единственная причина, которую я обнаружил, заключалась в том, что они применяют LOOCV для надежного PCA. К сожалению, команда поддержки не захотела отвечать на мой вопрос, так как у меня есть только демо-версия их программного обеспечения.
источник
tempRepmat(kk,kk) = -1
строки? Разве предыдущая строка уже не гарантирует, чтоtempRepmat(kk,kk)
равно -1? Кроме того, почему минусы? В любом случае ошибка будет возведена в квадрат, так что я правильно понимаю, что если убрать минусы, ничего не изменится?Ответы:
То, что вы делаете, неправильно: вычислять PRESS для PCA не имеет смысла! В частности, проблема заключается в вашем шаге № 5.
Наивный подход к PRESS для PCA
Пусть набор данных состоит из точек в d- мерном пространстве: x ( i ) ∈ R d ,n d x(i)∈Rd,i=1…n x(i) X(−i) k U(−i) ∥∥x(i)−x^(i)∥∥2=∥∥x(i)−U(−i)[U(−i)]⊤x(i)∥∥2 i
Для простоты я игнорирую проблемы центрирования и масштабирования здесь.
Наивный подход неправильный
Проблема выше в том, что мы используем для вычисления предсказания , и это очень плохо.x(i) x^(i)
Обратите внимание на принципиальное отличие от случая регрессии, где формула ошибки восстановления в основном такая же: , но прогноз вычисляется с использованием переменных-предикторов, а не с использованием . Это невозможно в PCA, потому что в PCA нет зависимых и независимых переменных: все переменные обрабатываются вместе.∥∥y(i)−y^(i)∥∥2 y^(i) y(i)
На практике это означает, что PRESS, как вычислено выше, может уменьшаться с увеличением количества компонентов и никогда не достигать минимума. Что заставило бы думать, что все компоненты значимы. Или, может быть, в некоторых случаях он достигает минимума, но все же имеет тенденцию переоценивать и переоценивать оптимальную размерность.k d
Правильный подход
Существует несколько возможных подходов, см. Bro et al. (2008) Перекрестная проверка моделей компонентов: критический взгляд на текущие методы для обзора и сравнения. Один из подходов состоит в том, чтобы исключить одно измерение одной точки данных за раз (т.е. вместо ), чтобы обучающие данные стали матрицей с одним отсутствующим значением и затем для прогнозирования («вменения») этого недостающего значения с помощью PCA. (Конечно, можно произвольно удерживать некоторую большую часть матричных элементов, например, 10%). Проблема в том, что вычисление PCA с пропущенными значениями может быть довольно медленным в вычислительном отношении (оно основывается на алгоритме EM), но здесь необходимо многократно повторяться. Обновление: см. Http://alexhwilliams.info/itsneuronalblog/2018/02/26/crossval/x(i)j x(i) для хорошего обсуждения и реализации Python (PCA с отсутствующими значениями реализуется через чередующиеся наименьшие квадраты).
Подход, который я нашел гораздо более практичным, состоит в том, чтобы исключать одну точку данных за раз, вычислять PCA на данных обучения (точно так же, как указано выше), но затем циклически проходить измерения , оставьте их по одному и вычислите ошибку восстановления, используя остальные. Это может быть довольно запутанным в начале, и формулы имеют тенденцию становиться довольно грязными, но реализация довольно проста. Позвольте мне сначала дать (несколько пугающую) формулу, а затем кратко объяснить ее:x(i) x(i)
Рассмотрим внутренний цикл здесь. Мы пропустили одну точку и вычислили основных компонентов на обучающих данных, . Теперь мы сохраняем каждое значение в качестве теста и используем оставшиеся измерения для выполнения прогноза , Предсказание - это координата "проекции" (в смысле наименьших квадратов) на подпространство, охватываемое по . Чтобы вычислить его, найдите точку в пространстве ПК которая ближе всего кx(i) k U(−i) x(i)j x(i)−j∈Rd−1 x^(i)j j x(i)−j U(−i) z^ Rk x(i)−j путем вычисления где равно с строкой выгнан, и означает псевдообратный. Теперь отобразите обратно в исходное пространство: и взять его координату . z^=[U(−i)−j]+x(i)−j∈Rk U(−i)−j U(−i) j [⋅]+ z^ U(−i)[U(−i)−j]+x(i)−j j [⋅]j
Приближение к правильному подходу
Я не совсем понимаю дополнительную нормализацию, используемую в PLS_Toolbox, но вот один подход, который идет в том же направлении.
Есть еще один способ отобразить на пространство главных компонентов: , т.е. просто сделайте транспонирование вместо псевдообратного. Другими словами, измерение, оставленное для тестирования, вообще не учитывается, и соответствующие веса также просто выбрасываются. Я думаю, что это должно быть менее точно, но часто может быть приемлемым. Хорошо, что полученная формула теперь может быть векторизована следующим образом (я опускаю вычисления):x(i)−j z^approx=[U(−i)−j]⊤x(i)−j
где я написал как для компактности, а означает установку всех недиагональных элементов на ноль. Обратите внимание, что эта формула выглядит точно так же, как первая (наивная ПРЕССА) с небольшой коррекцией! Также обратите внимание, что это исправление зависит только от диагонали , как в коде PLS_Toolbox. Однако формула все еще отличается от того, что, по-видимому, реализовано в PLS_Toolbox, и эту разницу я не могу объяснить. U d i a g {⋅} U U ⊤U(−i) U diag{⋅} UU⊤
Обновление (февраль 2018 г.): выше я назвал одну процедуру «правильной», а другую «приблизительной», но я больше не уверен, что это имеет смысл. Обе процедуры имеют смысл, и я думаю, что ни одна из них не является более правильной. Мне очень нравится, что «приблизительная» процедура имеет более простую формулу. Кроме того, я помню, что у меня был какой-то набор данных, где «приблизительная» процедура дала результаты, которые выглядели более значимыми. К сожалению, я больше не помню деталей.
Примеры
Вот как эти методы сравниваются для двух известных наборов данных: набор данных Iris и набор данных wine. Обратите внимание, что наивный метод создает монотонно убывающую кривую, тогда как два других метода дают кривую с минимумом. Отметим далее, что в случае радужной оболочки, приближенный метод предлагает 1 ПК в качестве оптимального числа, а псевдообратный метод предлагает 2 ПК. (И, глядя на любую диаграмму рассеяния PCA для набора данных Iris, кажется, что оба первых ПК несут некоторый сигнал.) И в случае с вином псевдообратный метод явно указывает на 3 ПК, тогда как приблизительный метод не может выбирать между 3 и 5.
Код Matlab для перекрестной проверки и построения результатов
источник
i
Чтобы добавить еще более общее замечание к хорошему ответу @ amoeba:
Одно практическое и решающее различие между моделями с надзором и без надзора заключается в том, что для моделей без надзора нужно гораздо больше думать, что вы считаете эквивалентным, а что нет.
Подконтрольные модели всегда имеют свой конечный результат так, что вам не нужно сильно беспокоиться об этом: по определению и конструкции утверждает, что имеет то же значение, что и , так что вы можете напрямую сравнить его. у уy^ y^ y
Чтобы создать значимые показатели производительности, вам нужно подумать, какие виды свободы модели не имеют смысла для вашего приложения, а какие нет. Это привело бы к ПРЕССУ на счетах, возможно (обычно?) После некоторого прокрутообразного вращения / переворота.
НАЖМИТЕ на х Я думаю (у меня нет времени, чтобы выяснить, что делают их 2 строки кода - но, возможно, вы могли бы пройтись по строкам и посмотреть?):
Чтобы получить показатель, который полезен для определения хорошей сложности модели, из показателя, который дает степень соответствия, которая обычно будет увеличиваться до тех пор, пока не будет достигнута модель полного ранга, необходимо наложить штраф на слишком сложные модели. Что, в свою очередь, означает, что это наказание является а) критическим и б) корректировка штрафа будет корректировать выбранную сложность.
Примечание: я просто хотел бы добавить, что я буду очень осторожен с этим типом автоматической оптимизации сложности моделей. По моему опыту, многие из этих алгоритмов дают только псевдообъективность и часто стоят за счет хорошей работы только для определенных типов данных.
источник