n, p가 둘 다 크면 PCA가 너무 느림 : 대안?


9

문제 설정

2D로 시각화하려고하는 높은 차원 (4096)의 데이터 포인트 (이미지)가 있습니다. 이를 위해 Karpathy의 다음 예제 코드 와 비슷한 방식으로 t-sne을 사용하고 있습니다.

scikit 배우기 문서는 먼저 데이터의 차원을 낮추기 위해 PCA를 사용하는 것이 좋습니다 :

피처 수가 매우 많은 경우 차원 수를 적당한 양 (예 : 50)으로 줄이려면 다른 차원 축소 방법 (예 : 밀도가 높은 데이터의 경우 PCA 또는 TruncatedSVD)을 사용하는 것이 좋습니다.

Javas에서 PCA를 수행하기 위해 Darks.Liu 의이 코드를 사용하고 있습니다.

//C=X*X^t / m
DoubleMatrix covMatrix = source.mmul(source.transpose()).div(source.columns);
ComplexDoubleMatrix eigVal = Eigen.eigenvalues(covMatrix);
ComplexDoubleMatrix[] eigVectorsVal = Eigen.eigenvectors(covMatrix);
ComplexDoubleMatrix eigVectors = eigVectorsVal[0];
//Sort sigen vector from big to small by eigen values 
List<PCABean> beans = new ArrayList<PCA.PCABean>();
for (int i = 0; i < eigVectors.columns; i++) {
    beans.add(new PCABean(eigVal.get(i).real(), eigVectors.getColumn(i)));
}
Collections.sort(beans);
DoubleMatrix newVec = new DoubleMatrix(dimension, beans.get(0).vector.rows);
for (int i = 0; i < dimension; i++) {
    ComplexDoubleMatrix dm = beans.get(i).vector;
    DoubleMatrix real = dm.getReal();
    newVec.putRow(i, real);
}
return newVec.mmul(source);

선형 대수 연산에 jblas 를 사용 하는데 , 내가 읽은 것 중 가장 빠른 옵션이 될 것입니다. 그러나 고유 벡터와 고유 값 (3,4 행)을 계산하면 병목 현상이 발생합니다 (~ 10 분,이 단계에서 감당할 수있는 시간보다 훨씬 깁니다).

Kernel PCA에 대해 읽었습니다. 커널 PCA는 차원이 매우 큰 경우에 적합하지만 런타임은 영형()차원 예제 수가 많은 경우를 다루고 싶기 때문에 문제가 될 수 있습니다 .

내가 알듯이 내 옵션은 PCA를 "최적화"하거나 본질적으로 더 빠른 다른 차원 축소 방법을 선택하는 것입니다.

내 질문

  1. PCA가 "오프라인"방식으로 사용될 수 있다는 희망이 있습니까? 즉, 큰 데이터 세트의 이미지를 사용하여 이미지에 대해 PCA를 수행 한 다음 계산 된 주요 구성 요소를 사용하여 다른 (새로운!) 데이터 포인트 의 차원을 줄 입니까?
  2. 예를 들어 상위 100 대 구성 요소에만 관심이 있다는 것을 미리 알고 있다고 가정하면 고유 벡터 계산 속도를 높일 수 있습니까?
  3. 내 경우에 (즉, t-sne을 적용하기 전에) PCA보다 더 빠른 대안적인 차원 축소 방법이 있습니까? Java로 쉽게 구현할 수있는 것을 찾고 있습니다.

답변:


8

질문 1 : 데이터 매트릭스를 관찰했다고 가정 해 봅시다. 엑스아르 자형×. 이것으로부터 고유 분해를 계산할 수 있습니다엑스엑스=Λ. 문제는 이제 같은 인구 집단에서 새로운 데이터를 얻는다면 매트릭스로 수집 할 수 있습니다아르 자형미디엄×, 의지 이상적인 직교 회전에 가깝다 ? 이런 종류의 질문은 Davis-Kahan 정리 와 일반적으로 행렬 교란 이론에 의해 해결됩니다 (사본을 얻을 수 있다면 Stewart와 Sun의 1990 교과서는 표준 참조입니다).

질문 2 : 상단 만 필요하다는 것을 알면 확실히 속도를 높일 수 있습니다 케이고유 벡터. RI rARPACK는이를 위해 사용 한다. 어쨌든 모든 포트란 래퍼이기 때문에 Java와 동등한 것이 있다고 확신합니다.

질문 3 : Java 구현에 대해서는 아무것도 모르지만 스레드는 CV 스레드 와 마찬가지로 PCA 속도를 논의 합니다. 이런 종류의 일에 대한 많은 연구가 있으며 낮은 순위 근사 또는 무작위 화와 같은 것을 사용하는 수많은 방법이 있습니다.


3

사용중인 코드는 전체 행렬을 반전시킵니다. 이것은 아마도 O (p ^ 3) 일 것입니다. O (p ^ 2)의 결과를 근사 할 수는 있지만 여전히 느립니다 (그러나 아마도 100 배 빠릅니다). 기본적으로 임의의 벡터를 취하고 전력 반복을 수행하십시오. 확률이 높으면 첫 번째 고유 벡터의 근사값을 얻을 수 있습니다. 그런 다음 행렬에서이 인수를 제거하고 반복하여 두 번째 값을 얻습니다. 기타.

그러나 ELKI의 빠른 Barnes Hut tSNE 구현이 커버 트리와 같은 인덱스를 사용하여 데이터에서 작동하는지 시도해 보셨습니까? 다른 사람들이 실패했을 때 그 구현이 잘 작동했습니다.


3
"whp"는 무엇입니까? 서?
Kodiologist

높은 확률로. 통계 문헌을 참조하십시오.
종료-익명-무스

2

간단하고 직접적인 방식으로 치수 축소에 영향을 미치는 것이 목표라면 교대 최소 제곱 (ALS) 기법을 시도 할 수 있습니다. 예를 들어 Apache Spark mlib에는 ALS 구현이 있으며 Java API를 제공한다고 생각합니다. 이것은 당신에게×케이 매트릭스와 케이×매트릭스. 그만큼케이× 행렬은 시각화 가능한 행 벡터를 포함합니다.

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