我正在做一个数据集(点的集合)的kernel density estimation
。
estimation process
是ok的,问题是,当我试图获得density value
为每个点,速度非常慢:
from sklearn.neighbors import KernelDensity
# this speed is ok
kde = KernelDensity(bandwidth=2.0,atol=0.0005,rtol=0.01).fit(sample)
# this is very slow
kde_result = kde.score_samples(sample)
样品由300,000 (x,y) points
组成。
我想知道是否有可能使它平行运行,这样速度会更快?
例如,也许我可以将sample
分成更小的集合,并同时为每个集合运行score_samples
?具体来说:
- 我一点也不熟悉
parallel computing
。所以我想知道这是否适用于我的情况? - 如果这真的能加快进程,我该怎么做?我只是在
ipython notebook
运行脚本,并没有在这方面的经验,有任何好的和简单的例子,我的情况下?
我正在看http://ipython.org/ipython-doc/dev/parallel/parallel_intro.html
更新:import cProfile
cProfile.run('kde.score_samples(sample)')
64 function calls in 8.653 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 8.653 8.653 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 _methods.py:31(_sum)
2 0.000 0.000 0.000 0.000 base.py:870(isspmatrix)
1 0.000 0.000 8.653 8.653 kde.py:133(score_samples)
4 0.000 0.000 0.000 0.000 numeric.py:464(asanyarray)
2 0.000 0.000 0.000 0.000 shape_base.py:60(atleast_2d)
2 0.000 0.000 0.000 0.000 validation.py:105(_num_samples)
2 0.000 0.000 0.000 0.000 validation.py:126(_shape_repr)
6 0.000 0.000 0.000 0.000 validation.py:153(<genexpr>)
2 0.000 0.000 0.000 0.000 validation.py:268(check_array)
2 0.000 0.000 0.000 0.000 validation.py:43(_assert_all_finite)
6 0.000 0.000 0.000 0.000 {hasattr}
4 0.000 0.000 0.000 0.000 {isinstance}
12 0.000 0.000 0.000 0.000 {len}
2 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
2 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}
1 8.652 8.652 8.652 8.652 {method 'kernel_density' of 'sklearn.neighbors.kd_tree.BinaryTree' objects}
2 0.000 0.000 0.000 0.000 {method 'reduce' of 'numpy.ufunc' objects}
2 0.000 0.000 0.000 0.000 {method 'sum' of 'numpy.ndarray' objects}
6 0.000 0.000 0.000 0.000 {numpy.core.multiarray.array}
下面是一个使用内置多处理模块并行化的简单示例:
import numpy as np
import multiprocessing
from sklearn.neighbors import KernelDensity
def parrallel_score_samples(kde, samples, thread_count=int(0.875 * multiprocessing.cpu_count())):
with multiprocessing.Pool(thread_count) as p:
return np.concatenate(p.map(kde.score_samples, np.array_split(samples, thread_count)))
kde = KernelDensity(bandwidth=2.0,atol=0.0005,rtol=0.01).fit(sample)
kde_result = parrallel_score_samples(kde, sample)
从上面的代码中可以看到,multiprocessing.Pool
允许您在示例的一个子集上映射执行kde.score_samples
的工作进程池。如果你的处理器有足够的内核,加速将是显著的。