Sklearn TFIDF vectorizer для работы в качестве параллельных заданий

Как запустить sklearn TFIDF vectorizer (и векторный указатель COUNT) для выполнения параллельных заданий? Что-то похожее на параметр n_jobs = -1 в других моделях sklearn.

Ответ 1

Это невозможно, потому что нет возможности распараллеливать/распространять доступ к лексике, которая необходима для этих векторизаторов.

Чтобы выполнить параллелизацию вектора вектора, используйте пример, используя этот векторризатор для обучения (и оценки) классификатора партиями. Подобный рабочий процесс также работает для распараллеливания, поскольку входные термины сопоставляются с одинаковыми векторными индексами без какой-либо связи между параллельными рабочими.

Просто вычислите частичные матрицы term-doc отдельно и объедините их, как только будут выполнены все задания. На этом этапе вы можете также запустить TfidfTransformer в конкатенированной матрице.

Самым существенным недостатком не сохранения словарного запаса входных терминов является то, что трудно определить, какие термины сопоставляются с каким столбцом в конечной матрице (т.е. обратное преобразование). Единственное эффективное отображение - использовать функцию хэширования в терминах, чтобы увидеть, к какому столбцу/индексу присвоено. Для обратного преобразования вам нужно будет сделать это для всех уникальных терминов (т.е. Вашего словаря).

Ответ 2

Предыдущий ответ хорош, однако я хотел бы расширить пример и то, что HashingVectorizer будет объявлен устаревшим. Я привожу здесь и отдельный пример, где вы можете увидеть прошедшее время. В основном после подгонки векторизатора (который трудно распараллелить) вы можете преобразовать (этот бит легче распараллелить).

У вас есть что-то вроде этого, чтобы соответствовать модели:

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)

Предыдущее решение является адаптацией отсюда.

Я надеюсь, что это помогает. В моем случае это значительно сокращает время.