我对在大数据矩阵的不同随机采样子集上执行统计感兴趣,现在我的代码中的瓶颈是实际的子采样。这对我来说似乎很奇怪,因为在二次采样数据上有相当数量的O(N ^ 2)距离计算。我根本没有修改子样本,只是看着它们。
using Distributions, Distances
function test_subsetting(X; batch_size=500, nloops=100)
nfeatures, nsamples = size(X)
ref_samples = X[:,1:10]
batch_inds = zeros(batch_size)
batch = zeros(nfeatures,batch_size)
d_matrix = zeros(batch_size,batch_size)
for i = 1:nloops
batch_inds = sort(sample(1:nsamples, batch_size, replace = false))
batch = X[:,batch_inds]
d_matrix = pairwise(SqEuclidean(), batch, ref_samples)
end
end
当我通过50000样本矩阵在5000特征上测试时:
X_test = randn(5000,50000);
我发现我花了大约一半的时间在_unsafe_getindex
multidimensional.jl
,而另一半花在距离计算上。
有没有更有效的方法来解决这个问题?
答案 0 :(得分:3)
这对我来说是julia 0.5:
julia> using Distances, Distributions
julia> X = randn(500,1000);
julia> S = sample(1:1000,500,replace=false);
julia> M = view(X, :, S);
julia> S2 = sample(1:1000,500,replace=false);
julia> R = view(X, :, S2);
julia> pairwise(SqEuclidean(), M, R)
500×500 Array{Float64,2}:
994.67 ...
...
关于julia 0.5的 view
在julia 0.4上被称为slice
(或sub
,这里它们将是相同的)。不要与ArrayViews.view
混淆,view
执行类似但具有完全不同的实现。
从理论上讲,您似乎应该只能将slice
替换为At_mul_B!
,但似乎julia 0.4上缺少{{1}}方法。所以你可能会被困在制作副本。
答案 1 :(得分:2)
如果您乐意“预先生成”随后在运行时引用的随机索引的大矩阵,则可以完全缩短“采样”时间。您甚至可以在每次使用之前为该矩阵提供一些“行和列”洗牌,并且成本最低。
另外,为什么你需要排序呢?当然,这会使随机抽样失败,并引入不必要的计算?