【发布时间】:2015-12-11 16:42:03
【问题描述】:
我有一个很大的数组artist_topic_probs(112,312 项行乘约 100 个特征列),我想计算该数组中随机行对(大样本)之间的成对余弦相似度。这是我当前代码的相关位
# the number of random pairs to check (10 million here)
random_sample_size=10000000
# I want to make sure they're unique, and that I'm never comparing a row to itself
# so I generate my set of comparisons like so:
np.random.seed(99)
comps = set()
while len(comps)<random_sample_size:
a = np.random.randint(0,112312)
b= np.random.randint(0,112312)
if a!=b:
comp = tuple(sorted([a,b]))
comps.add(comp)
# convert to list at the end to ensure sort order
# not positive if this is needed...I've seen conflicting opinions
comps = list(sorted(comps))
这会生成一个元组列表,其中每个是我将计算相似度的两行。然后我只用一个简单的循环来计算所有的相似度:
c_dists = []
from scipy.spatial.distance import cosine
for a,b in comps:
c_dists.append(cosine(artist_topic_probs[a],artist_topic_probs[b]))
(当然,cosine 这里给出了距离,而不是相似度,但是我们可以很容易地用sim = 1.0 - dist 得到它。我在标题中使用了相似度,因为这是更常用的术语)
这很好用,但不是太快,我需要多次重复该过程。我有 32 个内核可供使用,所以并行化似乎是一个不错的选择,但我不确定最好的方法。我的想法是这样的:
pool = mp.Pool(processes=32)
c_dists = [pool.apply(cosine, args=(artist_topic_probs[a],artist_topic_probs[b]))
for a,b in comps]
但是在我的笔记本电脑上用一些测试数据测试这种方法并没有奏效(它只是挂起,或者至少比我厌倦了等待并杀死它的简单循环花费了更长的时间)。我担心矩阵的索引是某种瓶颈,但我不确定。关于如何有效地并行化(或以其他方式加快进程)的任何想法?
【问题讨论】:
-
建议使用Apache Spark
-
我不确定这个问题空间是否适合并行化......至少不是你目前描述的方式......
-
我已经考虑过这个,但对于一个相对简单的问题来说,这似乎是一把大锤。但我想一般的方法是将数组广播给所有执行者,然后在要比较的元组的 RDD 上做一个简单的映射? IE。 (假设
comps现在是一个 RDD)arr = sc.broadcast(artist_topic_probs); c_dists = comps.map(lambda x: cosine(artist_topic_probs.value[x[0]],artist_topic_probs.value[x[1]]).collect()?
标签: python python-multiprocessing