Sklearn TFIDF矢量化程序作为并行作业运行

时间:2015-02-08 17:23:40

标签: python scikit-learn

如何运行sklearn TFIDF vectorizer(和COUNT vectorizer)作为并行作业运行?与其他sklearn模型中的n_jobs = -1参数类似的东西。

2 个答案:

答案 0 :(得分:11)

这不可能直接实现,因为无法并行/分发对这些矢量化程序所需词汇表的访问。

要执行并行文档向量化,请改用HashingVectorizer。 scikit docs使用此向量化工具提供an example批量训练(和评估)分类器。类似的工作流程也适用于并行化,因为输入术语映射到相同的矢量索引,而并行工作者之间没有任何通信。

只需单独计算部分term-doc矩阵,并在完成所有作业后将它们连接起来。此时,您还可以在连接矩阵上运行TfidfTransformer

不存储输入项词汇表的最显着的缺点是难以找出哪些项被映射到最终矩阵中的哪一列(即逆变换)。唯一有效的映射是在术语上使用散列函数来查看分配给哪个列/索引。对于逆变换,您需要对所有唯一的术语(即您的词汇表)执行此操作。

答案 1 :(得分:4)

Previous answer很好,但是我想在示例中进行扩展,并且不推荐使用HashingVectorizer。    我提供了here和独立的示例,您可以在其中查看经过的时间。    基本上,在安装矢量化器之后(很难并行化),您可以进行转换(此位更易于并行化)。

您可以通过以下方式来拟合模型:

print("Extracting tf-idf features")
tfidf_vectorizer = TfidfVectorizer(stop_words='english')
t0 = time()
tfidf = tfidf_vectorizer.fit(data_pd['text'])
print("done in %0.3fs." % (time() - t0))

您可以通过以下方式转换数据:

print("Transforming tf-idf features...")
tfidf = tfidf_vectorizer.transform(data_pd['text'])
print("done in %0.3fs." % (time() - t0))

这是您可以并行处理的部分,我建议类似以下内容:

import multiprocessing
import pandas as pd
import numpy as np
from multiprocessing import Pool
import scipy.sparse as sp

num_cores = multiprocessing.cpu_count()
num_partitions = num_cores-2 # I like to leave some cores for other
#processes
print(num_partitions)

def parallelize_dataframe(df, func):
    a = np.array_split(df, num_partitions)
    del df
    pool = Pool(num_cores)
    #df = pd.concat(pool.map(func, [a,b,c,d,e]))
    df = sp.vstack(pool.map(func, a), format='csr')
    pool.close()
    pool.join()
    return df

def test_func(data):
    #print("Process working on: ",data)
    tfidf_matrix = tfidf_vectorizer.transform(data["text"])
    #return pd.DataFrame(tfidf_matrix.toarray())
    return tfidf_matrix

#df = pd.DataFrame({'col': [0,1,2,3,4,5,6,7,8,9]})
#df =  data_pd
tfidf_parallel = parallelize_dataframe(data_pd, test_func)

先前的解决方案是对here的改编。

我希望它会有所帮助。就我而言,它大大减少了时间。