【问题标题】:Python Linear Regression in parallel - Scoop并行 Python 线性回归 - 独家新闻
【发布时间】:2019-07-03 13:28:41
【问题描述】:

我正在尝试使用 Python 的 Scoop 库从正态分布随机生成超过 10000000 个数据点(4 个特征,1 个目标变量)的线性回归。这是代码:

import pandas as pd
import numpy as np
import random
from scoop import futures
import statsmodels.api as sm
from time import time

def linreg(vals):
    global model
    model = sm.OLS(y_vals,X_vals).fit()
    return model
    print(model.summary())    

if __name__ == '__main__':

random.seed(42)
vals = pd.DataFrame(np.random.normal(loc = 3, scale = 100, size =(10000000,5)))
vals.columns = ['dep', 'ind1', 'ind2', 'ind3', 'ind4']
y_vals = vals['dep']
X_vals = vals[['ind1', 'ind2', 'ind3', 'ind4']]

bt = time()
model_vals = list(map(linreg, [1,2,3]))
mval = model_vals[0]
print(mval.summary())
serial_time = time() - bt

bt1 = time()
model_vals_1 = list(futures.map(linreg, [1,2,3]))
mval_1 = model_vals_1[0]
print(mval_1.summary())
parallel_time = time() - bt1

print(serial_time, parallel_time)`

然而,在那之后,回归摘要确实是串行生成的——通过 Python 的标准 map 函数——一个错误:

Traceback(最近一次调用最后一次):文件“C:\Users\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\runpy.py”,第 193 行,在 _run_module_as_main“main”中, mod_spec) 文件“C:\Users\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\runpy.py”,第 85 行,_run_code exec(code, run_globals) 文件“C:\Users\ niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop\bootstrap__main__.py”,第 302 行,在 b.main() 文件“C:\Users\niccolo.gentile\AppData \Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop\bootstrap__main__.py”,第 92 行,在主 self.run() 文件“C:\Users\niccolo.gentile\AppData\Local\Continuum \anaconda3\envs\tensorenviron\lib\site-packages\scoop\bootstrap__main__.py”,第 290 行,在运行 futures_startup() 文件“C:\Users\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron \lib\site-packages\scoop\bootstrap__main__.py",第 271 行,在 futures_startup run_name="main" 文件“C:\User s\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop\futures.py",第 64 行,在 _startup 结果 = _controller.switch(rootFuture, *args, **kargs ) 文件“C:\Users\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop_control.py”,第 253 行,在 runController 中引发 future.exceptionValue 文件“C:\Users \niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop_control.py",第 127 行,在 runFuture future.resultValue = future.callable(*future.args, **future. kargs)文件“C:\Users\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\runpy.py”,第 263 行,在 run_path pkg_name=pkg_name,script_name=fname)文件“C:\ Users\niccolo.gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\runpy.py”,第 96 行,_run_module_code mod_name, mod_spec, pkg_name, script_name) 文件“C:\Users\niccolo.gentile\AppData \Local\Continuum\anaconda3\envs\tensorenviron\lib\runpy.py",第 85 行,在 _run_code exec(code, run_globals) 文件“Scoop_map_linear_regression1.py”中,第 33 行,在 model_vals_1 = list(futures.map(linreg, [1,2,3])) 文件“C:\Users\niccolo. gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop\futures.py”,第 102 行,在 _mapGenerator 中用于 _waitAll(*futures) 中的未来:文件“C:\Users\niccolo. gentile\AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop\futures.py",第 358 行,_waitAll for f in _waitAny(future):文件“C:\Users\niccolo.gentile \AppData\Local\Continuum\anaconda3\envs\tensorenviron\lib\site-packages\scoop\futures.py",第 335 行,_waitAny raise childFuture.exceptionValue NameError: name 'y_vals' is not defined

是之后产生的。这意味着代码停在model_vals_1 = list(futures.map(linreg, [1,2,3]))

请注意,为了能够并行运行代码,必须从指定 -m scoop 参数的命令行启动,如下所示:

python -m scoop Scoop_map_linear_regression1.py

确实,如果在没有 -m scoop 参数的情况下启动它,它不会被并行化并且确实会实际运行,但只是使用 Python 内置的 map 函数的两倍(因此,串行运行两次),如你会在警告中得到报告。也就是说,在启动时不指定 -m scoop 参数,futures.map 将被 map 替换,而目标实际上是使用 futures.map 并行运行它。

这样做是为了避免人们回答他们通过简单地启动不带 -m scoop 参数的代码来解决问题,就像这里已经发生的那样:

Python Parallel Computing - Scoop

因此,该问题被错误地搁置为题外话,因为不再可重现。

提前非常感谢,任何评论都非常感谢和欢迎。

【问题讨论】:

    标签: python machine-learning parallel-processing linear-regression python-scoop


    【解决方案1】:

    解决方案是只传递[1],作为futures.map(但不一定是map)的第二个参数。

    确实,即使 linreg 函数不使用传递给 map 的第二个参数,它仍然决定了 linreg 函数将运行多少次。例如,考虑以下基本示例:

    def welcome(x):
        print('Hello world!')
    
    if __name__ == '__main__':
        a = list(map(welcome, [1,2]))
    

    welcome 函数实际上不需要任何参数,但输出仍然是

    Hello world!
    Hello world!
    

    重复两次,即作为第二个参数传递的列表的长度。

    在这种特定情况下,这意味着线性回归将按地图运行 3 次,尽管回归输出只会出现一次,因为在地图外调用摘要。

    关键是,相反,不可能使用 futures.map 多次运行线性回归。问题在于,显然,在第一次运行之后,它实际上删除了使用过的数据集,因此无法继续第二次和第三次运行,以及随之而来的

    NameError: name 'y_vals' 未定义

    在跟踪结束时抛出。这应该通过导航可见:scoop.futures source code

    没有全部看完,但我想问题应该与greenlet切换器有关。

    【讨论】:

      猜你喜欢
      • 2017-12-27
      • 2022-08-10
      • 2018-07-23
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 2018-07-31
      • 2017-01-21
      相关资源
      最近更新 更多