1

Я начинаю работать с python и машинным обучением. Я пытаюсь воспроизвести код для countvectorizer(), используя многопоточность. Я работаю с набором данных yelp для анализа настроений с использованием LogisticRegression. Это то, что я написал до сих пор:Threadpool в python не так быстро, как ожидалось

Фрагмент кода:

from multiprocessing.dummy import Pool as ThreadPool 
from threading import Thread, current_thread 
from functools import partial 
data = df['text'] 
rev = df['stars'] 


y = [] 
def product_helper(args): 
    return featureExtraction(*args) 


def featureExtraction(p,t):  
    temp = [0] * len(bag_of_words) 
    for word in p.split(): 
     if word in bag_of_words: 
      temp[bag_of_words.index(word)] += 1 

    return temp 


# function to be mapped over 
def calculateParallel(threads): 
    pool = ThreadPool(threads) 
    job_args = [(item_a, rev[i]) for i, item_a in enumerate(data)] 
    l = pool.map(product_helper,job_args) 
    pool.close() 
    pool.join() 
    return l 

temp_X = calculateParallel(12) 

Вот это только часть кода.

Объяснение:

df['text'] имеет все отзывы и df['stars'] имеет рейтинги (с 1 по 5). Я пытаюсь найти слово count vector temp_X, используя многопоточность. bag_of_words - это список некоторых частых слов выбора.

Вопрос:

без многопоточности, я был в состоянии вычислить temp_X примерно 24 минут и выше код занял 33 минут для набора данных обзоров размера 100k. Моя машина имеет 128 ГБ DRAM и 12 ядер (6 физических ядер с гиперпотоком, то есть нитей на сердечник = 2).

Что я здесь делаю неправильно?

ответ

1

весь Ваш код кажется CPU Bound, а не IO Bound .Вы только с использованием threads, которые находятся под GIL так эффективно работает только один поток плюс overheads.It работает только на один core.To работать на нескольких ядрах используют

Использование

import multiprocessing 
pool = multiprocessing.Pool() 
l = pool.map_async(product_helper,job_args) 

из multiprocessing.dummy импорта Бассейн как ThreadPool просто обертка над thread module.It использует только one core и не более того.

+0

спасибо. У меня больше вопросов. Где мы указываем количество ядер для использования? –

+0

@bhaskarjupudi он выберет отсутствие доступных сердечников ..... из multiprocessing.cpu_count() автоматически – vks

+0

Здесь, в фрагменте кода, который вы опубликовали, l является объектом. Как получить фактический список из этого объекта? –

0

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

Вот очень хороший документ объясняет, как это работает: http://www.dabeaz.com/python/UnderstandingGIL.pdf

Чтобы устранить проблему я предлагаю вам попробовать мульти обработки: https://pymotw.com/2/multiprocessing/basics.html

Примечание: многопроцессорная не является 100% equivilent многопоточности. Многопроцессорность будет выполняться параллельно, но разные процессы не будут обмениваться памятью, поэтому, если вы измените переменную в одном из них, она не будет изменена в другом процессе.

 Смежные вопросы

  • Нет связанных вопросов^_^