수십억 개의 0이 아닌 항목이 포함 된 3 백만 x 900만의 희소 행렬이 있습니다. R과 Python은 MAXINT가 아닌 항목이 0 인 희소 행렬을 허용하지 않기 때문에 Julia를 사용하는 이유를 발견하게되었습니다.메모리 효율이 좋은 스파 스 SVD/PCA (줄리아에서)?
이 데이터를 표준 편차로 스케일링하는 것은 쉬운 일이 아니지만, 비열한 것은 물론 200+ 테라 바이트 밀도의 고밀도 매트릭스를 생성 할 수있는 순진한 방식으로 진행되지 않습니다.
SVD 작업을 수행하는 관련 코드는 줄리아가 내 독서에서 https://github.com/JuliaLang/julia/blob/343b7f56fcc84b20cd1a9566fd548130bb883505/base/linalg/arnoldi.jl#L398
에서 찾을 수있다,이 코드의 핵심 요소는 AtA_or_AAt 구조체 및 그 주변 기능의 몇 가지, 특히 A_mul_B입니다! 사용자의 편의를
struct AtA_or_AAt{T,S} <: AbstractArray{T, 2}
A::S
buffer::Vector{T}
end
function AtA_or_AAt(A::AbstractMatrix{T}) where T
Tnew = typeof(zero(T)/sqrt(one(T)))
Anew = convert(AbstractMatrix{Tnew}, A)
AtA_or_AAt{Tnew,typeof(Anew)}(Anew, Vector{Tnew}(max(size(A)...)))
end
function A_mul_B!(y::StridedVector{T}, A::AtA_or_AAt{T}, x::StridedVector{T}) where T
if size(A.A, 1) >= size(A.A, 2)
A_mul_B!(A.buffer, A.A, x)
return Ac_mul_B!(y, A.A, A.buffer)
else
Ac_mul_B!(A.buffer, A.A, x)
return A_mul_B!(y, A.A, A.buffer)
end
end
size(A::AtA_or_AAt) = ntuple(i -> min(size(A.A)...), Val(2))
ishermitian(s::AtA_or_AAt) = true
이 마법이 일어나는 eigs 함수에 전달되고, 출력은 다음 SVD에 대한 관련 구성 요소에서 처리 아래 복사.
나는이 작업을 'flying'타입 셋업에 사용하는 가장 좋은 방법은 AtA_or_AAT_centered 버전을 사용하여 서브 클래스 AtA_or_AAT와 같은 일을하는 것이라고 생각한다. 그러나 동작을 모방하거나 컬럼을 저장하고 다시 정의한다. A_mul_B! 적절하게 기능하십시오.
그러나 저는 Julia를 사용하지 않고 이미 문제를 수정하는 데 어려움을 겪고 있습니다. 이것을 다시 시도하기 전에 이것이 적절한 공격 계획으로 간주된다면 의견을 얻을 수 있을지, 아니면 그러한 대규모 매트릭스에서 SVD를 수행하는 훨씬 쉬운 방법이 있다면 궁금합니다. 그것을 보았다. 그러나 나는 무엇인가 놓쳤을지도 모른다).
편집 : 기본 줄리아를 수정하는 대신 입력 희소 매트릭스의 희박 구조를 유지하는 "Centered Sparse Matrix" 패키지를 작성하려고 시도했지만 다양한 계산에서 적절한 경우 해당 열을 입력합니다. 그것은 구현 된 것으로 제한되어 있으며 작동합니다. 불행히도, 물건을 최적화하려고 시도한 꽤 광범위한 노력에도 불구하고 여전히 너무 느립니다.
어쩌면 내가 오해하고 있습니다 만, 당신이 scikit에서 핵심 PCA를 배울 수 있다고 생각합니까? –
나는 어떤 방법으로도 scikit-learn에서 데이터를 재 중심화하는 방법을 보지 못했습니다. 내가 놓친 게 있니? – James