У меня есть разреженный массив: term_doc
его размер 622256x715 Float64. Это очень скудно:
- Of its ~444,913,040 cells, only about 22,215 of them normally are nonempty.
- Из 622256 рядов занято только 4699.
- хотя из 715 столбцов все заняты.
Оператор, который я хотел бы выполнить, можно описать как возврат нормализованной строки и нормализованной версии этой матрицы.
Я написал наивную неразреженную версию:
function doUnsparseWay()
gc() #Force Garbage collect before I start (and periodically during). This uses alot of memory
term_doc
N = term_doc./sum(term_doc,1)
println("N done")
gc()
P = term_doc./sum(term_doc,2)
println("P done")
gc()
N[isnan(N)] = 0.0
P[isnan(P)] = 0.0
N,P,term_doc
end
Выполнение этого:
> @time N,P,term_doc= doUnsparseWay()
outputs:
N done
P done
elapsed time: 30.97332475 seconds (14466 MB allocated, 5.15% gc time in 13 pauses with 3 full sweep)
Это довольно просто. Жрет память, и вылетает, если сборка мусора не происходит в нужное время (таким образом я вызываю это вручную). Но это достаточно быстро
Я хотел заставить его работать на разреженной матрице. Чтобы не пережевывать мою память, и потому что логически это более быстрая операция - нужно оперировать меньше клеток.
Я следовал предложениям из этот пост и из страница документации.
function doSparseWay()
term_doc::SparseMatrixCSC{Float64,Int64}
N= spzeros(size(term_doc)...)
N::SparseMatrixCSC{Float64,Int64}
for (doc,total_terms::Float64) in enumerate(sum(term_doc,1))
if total_terms == 0
continue
end
@fastmath @inbounds N[:,doc] = term_doc[:,doc]./total_terms
end
println("N done")
P = spzeros(size(term_doc)...)'
P::SparseMatrixCSC{Float64,Int64}
gfs = sum(term_doc,2)[:]
gfs::Array{Float64,1}
nterms = size(term_doc,1)
nterms::Int64
term_doc = term_doc'
@inbounds @simd for term in 1:nterms
@fastmath @inbounds P[:,term] = term_doc[:,term]/gfs[term]
end
println("P done")
P=P'
N[isnan(N)] = 0.0
P[isnan(P)] = 0.0
N,P,term_doc
end
Это никогда не завершается. Он доходит до вывода «N Done», но никогда не выводит «P Done». Я оставил его включенным на несколько часов.
- Как оптимизировать его, чтобы он мог завершиться в разумные сроки?
- Или, если это невозможно, объясните, почему.