파이썬에서 매우 크고 희소 한 인접 행렬의 모든 고유 값을 계산하는 가장 빠른 방법은 무엇입니까?


12

scipy.sparse.linalg.eigsh를 사용하는 것보다 매우 크고 희소 한 인접 행렬의 모든 고유 값과 고유 벡터를 계산하는 더 빠른 방법이 있는지 알아 내려고 노력 중입니다. 행렬의 대칭 속성. 인접 행렬도 바이너리이므로 더 빠른 방법이 있다고 생각합니다.

임의의 1000x1000 희소 인접 행렬을 만들고 x230 우분투 13.04 랩톱의 여러 방법을 비교했습니다.

  • scipy.sparse.linalg.eigs : 0.65 초
  • scipy.sparse.linalg.eigsh : 0.44 초
  • scipy.linalg.eig : 6.09 초
  • scipy.linalg.eigh : 1.60 초

희소 eigs와 eigsh를 사용하여 원하는 고유 값과 고유 벡터의 개수 인 k를 행렬의 순위로 설정했습니다.

문제는 더 큰 행렬로 시작합니다. 9000x9000 행렬에서 scipy.sparse.linalg.eigsh는 45 분이 걸렸습니다!


1
NB. scipy.sparse.linalg.eigsh는 ARPACK
pv입니다.

4
후속 조치를 취하면 행렬이 클수록 내부 고유 값 (즉, 가장 큰 고유 값 또는 가장 작은 고유 값)을 정확하게 계산할 가능성이 줄어 듭니다. 분해하는 매트릭스에서 어떤 정보가 필요합니까?
제프 옥스 베리

1
이 질문은 여기에 게시 되었습니다 . 교차 게시 버전을 닫는 것이 좋습니다.
Aron Ahmadia

2
A ^ k를 계산하고 싶습니다. 다시 생각한 후, 그러한 행렬을 사용하면 고유 분해를 사용하는 것보다 직접 곱셈 ( A A ...) 을 계산하는 것이 훨씬 빠릅니다 . 물론, 그것은 k에 달려 있습니다.
Noam Peled

2
예, 직접하십시오. 고유 분해 결과는 드물지 않으므로 스토리지 문제가 발생합니다 (k가 충분히 크면 A ^ k도 아닙니다). 관련 stackoverflow.com/a/9495457/424631
dranxo

답변:


6

FILTLAN 은 희소 대칭 행렬의 내부 고유 값을 계산하기위한 C ++ 라이브러리입니다. 이것에 전념하는 전체 패키지가 있다는 사실은 꽤 어려운 문제라는 것을 알려줍니다. 대칭 행렬의 최대 또는 최소 소수의 고유 값을 찾는 것은 쉬프트 / 반전 및 Lanczos 알고리즘을 사용하여 수행 할 수 있지만 스펙트럼의 중간은 또 다른 문제입니다. 이것을 사용하려면 SWIG를 사용하여 파이썬에서 C ++ 프로그램을 호출 할 수 있습니다.

최종 목표가 행렬의 큰 거듭 제곱을 계산하는 것이라면, 가장 큰 고유 값에 해당하는 고유 벡터를 계산할 수 있습니다.

즉, 실제로 전력을 직접 계산하는 것이 더 나을 수도 있습니다. 더 높은 전력을 계산할수록 점점 더 적어 지므로 더 많은 메모리를 차지합니다. 가 얼마나 높은가에 따라 결국 밀도가 높은 매트릭스로 전환 할 수 있습니다.k

이것들이 이미 당신에게 분명하다면 용서하십시오 : numpy에게 float 대신 정수로 구성되어 있음을 말함으로써 행렬의 이진 특성을 활용할 수 있습니다.

a = np.zeros(100,dtype=np.uint)

이렇게하면 공간을 절약 할 수 있습니다. 행렬 곱셈을 차단하여 시간을 절약 할 수 있습니다 (메모리는 아님). 계산을 원한다고 가정하십시오 . 를 계산 다음 를 얻기 위해 이것을 제곱하고 을 얻기 위해 이것을 제곱합니다 . 그런 식으로, 당신이 할 행렬 곱셈 대신 곱셈. A 2 A 4 A 8log 2 k kA16A2A4A8log2kk

속도가 문제가되고 NVIDIA GPU가 있다면 Python에서 CUSP 또는 cuSPARSE와 같은 병렬 희소 선형 대수 라이브러리 호출을 탐색 할 수도 있습니다.


1

Daniel Shapero의 답변에 대해 언급하고 싶지만 SE 평판이 충분하지 않습니다.

받아 들여진 대답은 나를 혼란스럽게합니다. 시프트 인버트 모드는 내부 고유 값을 계산하는 데 쉽게 사용할 수 있다고 생각합니다. 참조 : https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

원래 질문에 대답하기 위해 : 큰 희소 행렬의 모든 고유 값을 원하는 경우는 거의 없습니다. 일반적으로 극단 또는 일부 내부 값 클러스터를 원합니다. 이 경우 Hermitian 행렬 eigsh이 더 빠릅니다. 비 에르 미트 인의 경우와 함께 가야합니다 eigs. 그리고 그들은 numpy eig나 보다 훨씬 빠릅니다 eigh.

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