주요 구성 요소의 수를 판별하기 위해 PCA에 대한 교차 유효성 검증을 수행하는 방법은 무엇입니까?


12

주요 구성 요소 분석, PCA에 대한 자체 함수를 작성하려고합니다 (물론 이미 많이 작성되었지만 직접 구현하는 데 관심이 있습니다). 내가 만난 주요 문제는 교차 검증 단계와 예측 제곱합 (PRESS)을 계산하는 것입니다. 어떤 교차 유효성 검사를 사용하든 중요하지 않은 이론에 대한 질문이지만 LOOCV (Leave-One-Out Cross-Validation)를 고려하십시오. LOOCV를 수행하려면 다음과 같은 이론이 필요하다는 것을 알았습니다.

  1. 객체 삭제
  2. 나머지를 확장
  3. 몇 가지 구성 요소로 PCA 수행
  4. (2)에서 얻은 매개 변수에 따라 삭제 된 개체의 크기를 조정합니다
  5. PCA 모델에 따라 물체를 예측
  6. 이 객체에 대한 PRESS 계산
  7. 다른 알고리즘과 동일한 알고리즘을 다시 수행
  8. 모든 PRESS 값을 합산
  9. 이익

나는 현장에서 매우 새롭기 때문에 내가 옳다는 것을 확신하기 위해 결과를 가지고있는 일부 소프트웨어의 출력과 비교합니다 (일부 코드를 작성하려면 소프트웨어의 지침을 따릅니다). 잔차 제곱과 계산하는 것과 완전히 동일한 결과를 얻지 만 PRESS 계산은 문제가됩니다.R2

교차 유효성 검사 단계에서 구현 한 것이 옳은지 알려주세요.

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변수를 사용하여 추가적인 정규화를 수행 합니다. 제가 찾은 유일한 이유는 강력한 PCA에 LOOCV를 적용했기 때문입니다. 불행히도 지원 팀은 소프트웨어의 데모 버전 만 가지고 있기 때문에 내 질문에 대답하고 싶지 않았습니다.


추가 정규화 스 니펫을 이해하는지 추가 확인 : tempRepmat(kk,kk) = -1라인 의 역할은 무엇 입니까? 이전 줄이 이미 tempRepmat(kk,kk)-1 과 같지 않습니까? 또한 왜 마이너스입니까? 어쨌든 오류가 제곱 될 것이므로 마이너스를 제거하면 아무것도 변경되지 않는다는 것을 올바르게 알고 있습니까?
amoeba

나는 과거에 그것을 확인하고 있었고 아무것도 변하지 않을 것입니다. 맞습니다. 이러한 구현에서 계산 된 모든 PRESS 값 (모든 것을 요약하기 전에)이 자체 가중치를 갖기 때문에 강력한 PCA 구현과 일부 유사점을 발견했습니다.
키릴

답변에 제공된 MATLAB 코드와 동등한 R 코드를 찾고 현상금을 지불했습니다.
AIM_BLB

3
코드를 요구하는 @CSA는 여기서 논란의 여지가 없습니다 (아마도 의견 및 바운티를 통해). 스택 오버플 로에서 요청할 수 있어야합니다 . 코드를 복사하고 링크가있는 소스를 인용하며 번역을 요청할 수 있습니다. 나는 그 주제에 관한 모든 것을 믿습니다.
gung-모니 티 복원

답변:


21

당신이하는 일이 잘못되었습니다 : PCA에 대한 PRESS를 계산하는 것은 의미가 없습니다! 특히 문제는 5 단계에 있습니다.


PCA를위한 PRESS에 대한 순진한 접근

데이터 세트 를 차원 공간 에서 점으로 구성 합니다 : . 단일 테스트 데이터 포인트 대한 재구성 오류를 계산하려면 이 포인트를 제외 하고 트레이닝 세트 에 대해 PCA를 수행 하고 특정 수 의 주축을 사용합니다 열로 표시되고 와 같은 재구성 오류를 찾습니다. . 그런 다음 PRESS는 모든 테스트 샘플의 합계와 같습니다.d x ( i )R d ,nd(X) ( I ) X ( - I ) k는 U ( - I ) X ( I ) - (X) ( I ) 2 = X ( I ) - U ( - I ) [ U ( - I ) ] x ( i ) 2 i Px(i)Rd,i=1nx(i)X(i)kU(i)x(i)x^(i)2=x(i)U(i)[U(i)]x(i)2i합리적인 방정식은 다음과 같습니다.

PRESS=?i=1nx(i)U(i)[U(i)]x(i)2.

간단하게하기 위해 여기서는 중심 및 스케일링 문제를 무시하고 있습니다.

순진한 접근 방식이 잘못되었습니다

위의 문제는 을 사용하여 예측 을 계산 한다는 것은 매우 나쁜 것입니다.(X) ( I )x(i)x^(i)

재구성 오류의 공식이 기본적으로 동일한 회귀 분석과의 중요한 차이점에 유의하십시오. 이지만 예측 은 예측 변수를 사용하고 사용 하지 않고 계산됩니다 . PCA에는 종속적이고 독립적 인 변수가 없기 때문에 PCA에서는 불가능합니다. 모든 변수가 함께 처리됩니다.Y ( I ) Y ( I )y(i)y^(i)2y^(i)y(i)

실제로, 이는 위에서 계산 된 PRESS가 구성 요소 의 증가로 감소 할 수 있으며 최소값에 도달하지 않음을 의미합니다. 모든 구성 요소가 중요 하다고 생각 하게 만듭니다. 또는 경우에 따라 최소값에 도달하지만 여전히 최적의 치수를 과도하게 맞추고 과대 평가하는 경향이 있습니다.dkd

올바른 접근법

몇 가지 가능한 접근 방법이 있습니다 ( Bro et al. (2008) 구성 요소 모델의 교차 검증 : 개요 및 비교를위한 현재 방법비판적으로 살펴 봅니다 . 한 가지 방법은 한 번에 하나의 데이터 포인트의 한 차원 (예 : 대신 생략 하여 학습 데이터가 하나의 결 측값이있는 행렬이되도록하는 것입니다. 그런 다음 PCA를 사용하여이 결 측값을 예측 ( "대치")합니다. (물론 매트릭스 요소의 더 큰 부분, 예를 들어 10 %를 무작위로 유지할 수 있습니다). 문제는 결 측값이있는 PCA 계산이 계산 상 상당히 느릴 수 있지만 (EM 알고리즘에 의존 함) 여러 번 반복해야한다는 것입니다. 업데이트 : http://alexhwilliams.info/itsneuronalblog/2018/02/26/crossval/ 참조 (X) ( I )xj(i)x(i) 좋은 토론과 파이썬 구현 (결 측값이있는 PCA는 교대 최소 제곱을 통해 구현됩니다).

내가 훨씬 더 실제적인 하나의 데이터 포인트를 생략하는 것으로 발견 접근 방법 한 번에, 훈련 데이터에 대한 계산 PCA (위와 같이 정확하게)하지만 다음의 크기를 반복 할 한 번에 하나씩 남겨두고 나머지를 사용하여 재구성 오류를 계산하십시오. 이것은 처음에는 상당히 혼란 스러울 수 있으며 수식은 매우 혼란스러워지는 경향이 있지만 구현은 다소 간단합니다. 먼저 (어떤 무서운) 공식을 제시 한 다음 간단히 설명하겠습니다.x ( i )x(i)x(i)

PRESSPCA=i=1nj=1d|xj(i)[U(i)[Uj(i)]+xj(i)]j|2.

내부 루프를 고려하십시오. 우리는 한 포인트 빼고 훈련 데이터 에 대한 주요 구성 요소를 계산했습니다 . 이제 각 값 를 테스트로 유지하고 나머지 차원 을 사용하여 예측을 수행합니다. . 예측 은 IS 의 (최소 제곱 법 의미에서) "투영"좌표 번째 서브 스페이스 상 스팬 에 의해 . 이를 계산하려면 PC 공간 에서 가장 가까운 점 를 찾으십시오. k는 U ( - I ) (X) ( I ) - J ] +x(i)kU(i)xj(i)xj(i)Rd1x^j(i)jxj(i)U(i)z^Rkxj(i) 계산함으로써 여기서 는 이며 번째 행 추방하고 의사 역행렬 약자. 이제 를 원래 공간으로 다시 매핑 하십시오 : 로 번째 좌표 합니다. z^=[Uj(i)]+xj(i)RkUj(i)U(i)j[]+z^U(i)[Uj(i)]+xj(i)j[]j

올바른 접근 방식에 대한 근사치

PLS_Toolbox에 사용 된 추가 정규화를 이해하지 못하지만 동일한 방향으로 진행되는 한 가지 방법이 있습니다.

를 주요 구성 요소의 공간에 매핑하는 다른 방법이 있습니다 . 즉, 의사 역수 대신 조옮김 만 수행하면됩니다. 즉, 테스트를 위해 제외 된 치수는 전혀 계산되지 않으며 해당 가중치도 간단하게 추방됩니다. 나는 이것이 덜 정확해야한다고 생각하지만 종종 받아 들일 수 있습니다. 좋은 점은 결과 수식을 다음과 같이 벡터화 할 수 있다는 것입니다 (계산은 생략합니다).xj(i)z^approx=[Uj(i)]xj(i)

PRESSPCA,approx=i=1nj=1d|xj(i)[U(i)[Uj(i)]xj(i)]j|2=i=1n(IUU+diag{UU})x(i)2,

여기서 나는 압축을 위해 를 로 썼고 은 모든 비 대각선 요소를 0으로 설정하는 것을 의미합니다. 이 공식은 작은 수정으로 첫 번째 공식 (순진한 PRESS)과 똑같습니다! 이 수정 은 PLS_Toolbox 코드에서와 같이 의 대각선에만 의존 합니다. 그러나 공식은 여전히 ​​PLS_Toolbox에서 구현 된 것과 다르 므로이 차이점을 설명 할 수 없습니다. U d i a g {} U UU(i)Udiag{}UU

업데이트 (2018 년 2 월) : 위의 절차 중 하나는 "정확한"이고 다른 절차는 "대략적"이라고 불렀지 만 더 이상 이것이 의미가 있는지는 확실하지 않습니다. 두 절차 모두 의미가 있으며 더 정확하지 않다고 생각합니다. 나는 "대략적인"절차가 더 간단한 공식을 가지고 있다는 것을 정말로 좋아합니다. 또한 "근사한"프로 시저가보다 의미있는 결과를 산출 한 데이터 집합이 있다는 것을 기억합니다. 불행히도, 나는 더 이상 세부 사항을 기억하지 못합니다.


다음은 이러한 방법이 잘 알려진 두 가지 데이터 집합 인 아이리스 데이터 집합과 와인 데이터 집합에 대한 비교입니다. 순진 방법은 단조 감소 곡선을 생성하는 반면, 다른 두 방법은 최소 곡선을 생성합니다. 또한 아이리스의 경우 근사 방법은 1 개의 PC를 최적의 숫자로 제안하지만 유사 역법은 2 개의 PC를 제안합니다. (그리고 Iris 데이터 세트에 대한 PCA 산점도를 살펴보면 첫 번째 PC 모두 신호를 전달하는 것으로 보입니다.) 와인의 경우 의사 역 수법은 3 PC를 분명히 가리 키지 만 근사 방법은 3과 5 사이를 결정할 수 없습니다.

여기에 이미지 설명을 입력하십시오


교차 검증을 수행하고 결과를 플롯하는 Matlab 코드

function pca_loocv(X)

%// loop over data points 
for n=1:size(X,1)
    Xtrain = X([1:n-1 n+1:end],:);
    mu = mean(Xtrain);
    Xtrain = bsxfun(@minus, Xtrain, mu);
    [~,~,V] = svd(Xtrain, 'econ');
    Xtest = X(n,:);
    Xtest = bsxfun(@minus, Xtest, mu);

    %// loop over the number of PCs
    for j=1:min(size(V,2),25)
        P = V(:,1:j)*V(:,1:j)';        %//'
        err1 = Xtest * (eye(size(P)) - P);
        err2 = Xtest * (eye(size(P)) - P + diag(diag(P)));
        for k=1:size(Xtest,2)
            proj = Xtest(:,[1:k-1 k+1:end])*pinv(V([1:k-1 k+1:end],1:j))'*V(:,1:j)'; 
            err3(k) = Xtest(k) - proj(k);
        end

        error1(n,j) = sum(err1(:).^2);
        error2(n,j) = sum(err2(:).^2);
        error3(n,j) = sum(err3(:).^2);
    end    
end

error1 = sum(error1);
error2 = sum(error2);
error3 = sum(error3);
%// plotting code
figure
hold on
plot(error1, 'k.--')
plot(error2, 'r.-')
plot(error3, 'b.-')
legend({'Naive method', 'Approximate method', 'Pseudoinverse method'}, ...
    'Location', 'NorthWest')
legend boxoff
set(gca, 'XTick', 1:length(error1))
set(gca, 'YTick', [])
xlabel('Number of PCs')
ylabel('Cross-validation error')

답변 주셔서 감사합니다! 나는 그 종이를 알고있다. 그리고 거기에 설명 된 행 단위 교차 유효성 검사를 적용했습니다 (제공 한 코드와 정확히 일치하는 것으로 간주됩니다). PLS_Toolbox 소프트웨어와 비교하지만 LOOCV에는 실제로 이해하지 못하는 한 줄의 코드가 있습니다 (원래 질문으로 작성했습니다).
키릴

예, "행 단위 교차 유효성 검사"라고하며 구현은 괜찮은 것처럼 보이지만, 이는 교차 유효성 검사를 수행하는 나쁜 방법이며 (Bro 등에서 경험적으로 입증 된 바와 같이) 기본적으로 절대로 사용하지 마십시오! 이해하지 못하는 코드 라인과 관련하여 질문을 업데이트 하시겠습니까? 무엇을 말하는지 잘 모르겠습니다.
amoeba

문제는이 구현이 CV에서 최소에 도달하는 능력을 가지고있는 것 같습니다.
키릴

의 PRESS는 LOO % 설명 분산에 매우 가깝습니다-이것이 좋거나 나쁘다고 말하지는 않지만 확실히 알아야 할 것이 있습니다. 그리고 %처럼 PCA 모델로 1에 접근하게됩니다 분산 데이터 세트의 순위는,이 X를 눌러 0으로 접근 할 것이다 접근 설명x^x
SX에 불만 cbeleites을

@Kirill : 감사합니다. 코드 스 니펫은 이제 의미가 있습니다 (현재 사용되지 않는 위의 주석을 제거 할 수 있음). 어떻게해야할지 모르겠지만, 계산 된 예측 오류가 최소에 도달한다고하면 더 큰 (구성 요소 수, 즉 코드의 변수) 에 대해 약간의 페널티가 발생할 수 있습니다 . 솔직히 말해서, 나는 (내가 그것에 대한 이론적 타당성이 없다면), 특히 내 대답에 설명 된 것과 같은 더 나은 접근법이 있다는 것을 감안할 때 그러한 방법에 회의적입니다. ki
amoeba

1

@amoeba의 좋은 대답에 더 일반적인 요점을 추가하려면 다음을 수행하십시오.

감독 된 모델과 감독되지 않은 모델의 실용적이고 중요한 차이점은 감독되지 않은 모델의 경우 동등한 것으로 간주하는 것과 그렇지 않은 것을 훨씬 더 열심히 생각해야한다는 것입니다.

감독 모델은 항상 최종 출력이 당신이 이것에 대해 많이 신경 쓸 필요가없는 방법 : 정의와 구성에 의해, 같은 의미 있다고 주장 , 당신이 직접 비교할 수 있습니다. Y의 Yy^y^y

의미있는 성능 측정을 구성하려면 응용 프로그램에 어떤 모델의 자유가 의미가없고 어떤 것이 아닌지 생각해야합니다. 그것은 어떤 종류의 Procrustes와 같은 회전 / 플 래핑 후 점수에 압박을 가할 것입니다.

PRESS on x 내 추측은 (지금 2 줄의 코드가 무엇인지 알아낼 시간이 없지만-줄을 단계별로 살펴보고 살펴볼 수 있습니까?) :

전체 순위 모델에 도달 할 때까지 일반적으로 증가하는 적합도를 제공하는 측정 값에서 우수한 모델 복잡성을 결정하는 데 유용한 측정 값을 얻으려면 너무 복잡한 모델에 대해 벌칙을 부과해야합니다. 이는이 처벌이 a) 결정적이며 b) 페널티 조정이 선택한 복잡성을 조정한다는 것을 의미합니다.


참고 :이 유형의 자동 모델 복잡성 최적화에 매우주의를 기울이고 싶다고 덧붙이고 싶습니다. 내 경험상 이러한 알고리즘 중 많은 수는 의사 객관성 만 산출하며 종종 특정 유형의 데이터에 대해서만 잘 작동하는 비용이 듭니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.