我是python和机器学习的初学者。我尝试使用多线程重现countvectorizer()
的代码。我正在使用yelp数据集来使用LogisticRegression
进行情绪分析。这是我到目前为止所写的:
代码段:
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)。我试图使用多线程找到单词计数向量temp_X
。 bag_of_words
是一些常用词的列表。
问题:
如果没有多线程,我可以在大约24分钟内计算temp_X
,上面的代码需要33分钟才能获得100k评论的数据集。我的机器有128GB的DRAM和12个内核(6个具有超线程的物理内核,即每个内核的线程数= 2)。
我在这里做错了什么?
答案 0 :(得分:3)
您的整个代码似乎是CPU Bound
而不是IO Bound
。您只是使用threads
下的GIL
,因此只运行一个线程加上开销。它只运行于一个核心。要在多个核心上运行,请使用
使用
import multiprocessing
pool = multiprocessing.Pool()
l = pool.map_async(product_helper,job_args)
来自multiprocessing.dummy导入池作为ThreadPool只是thread
模块的包装器。它仅使用one core
而不是更多。
答案 1 :(得分:1)
Python和线程并不能很好地协同工作。有一个称为GIL(全局间隔器锁)的已知问题。基本上,interperter中有一个锁,它使所有线程不能并行运行(即使你有多个cpu内核)。 Python将简单地为每个线程一个接一个地给出几毫秒的cpu时间(并且它变慢的原因是这些线程之间的上下文切换的开销)。
这是一篇非常好的文档,解释了它的工作原理:http://www.dabeaz.com/python/UnderstandingGIL.pdf
要解决您的问题,我建议您尝试多处理: https://pymotw.com/2/multiprocessing/basics.html
注意:多处理与多线程不是100%相等。多处理将并行运行,但不同的进程不会共享内存,因此如果您更改其中一个变量,则不会在另一个进程中更改。