我在for循环中使用sklearn运行了几个机器学习算法,并想看看每个算法需要多长时间。问题是我还需要返回一个值,并且DONT想要多次运行它,因为每个算法都需要很长时间。有没有办法使用python的timeit模块或类似函数捕获返回值'clf'...
def RandomForest(train_input, train_output):
clf = ensemble.RandomForestClassifier(n_estimators=10)
clf.fit(train_input, train_output)
return clf
当我像这样调用函数时
t = Timer(lambda : RandomForest(trainX,trainy))
print t.timeit(number=1)
P.S。我也不想设置全局'clf'因为我可能想稍后进行多线程处理或多处理。
答案 0 :(得分:13)
问题归结为timeit._template_func没有返回函数的返回值:
def _template_func(setup, func):
"""Create a timer function. Used if the "statement" is a callable."""
def inner(_it, _timer, _func=func):
setup()
_t0 = _timer()
for _i in _it:
_func()
_t1 = _timer()
return _t1 - _t0
return inner
我们可以通过一些猴子修补来弯曲timeit
:
import timeit
import time
def _template_func(setup, func):
"""Create a timer function. Used if the "statement" is a callable."""
def inner(_it, _timer, _func=func):
setup()
_t0 = _timer()
for _i in _it:
retval = _func()
_t1 = _timer()
return _t1 - _t0, retval
return inner
timeit._template_func = _template_func
def foo():
time.sleep(1)
return 42
t = timeit.Timer(foo)
print(t.timeit(number=1))
返回
(1.0010340213775635, 42)
第一个值是timeit结果(以秒为单位),第二个值是函数的返回值。
请注意,上面的猴子补丁仅在{em>可调用传递timeit
时影响timeit.Timer
的行为。如果你传递一个字符串语句,那么你必须(类似地)修补timeit.template
字符串。
答案 1 :(得分:7)
有趣的是,我也在做机器学习,并且有类似的要求; - )
我通过写一个函数解决了它:
假设您想要时间:
clf = RandomForest(train_input, train_output)
然后做:
clf = time_fn( RandomForest, train_input, train_output )
Stdout会显示如下内容:
mymodule.RandomForest: 0.421609s
time_fn的代码:
import time
def time_fn( fn, *args, **kwargs ):
start = time.clock()
results = fn( *args, **kwargs )
end = time.clock()
fn_name = fn.__module__ + "." + fn.__name__
print fn_name + ": " + str(end-start) + "s"
return results
答案 2 :(得分:7)
对于Python 3.5,您可以覆盖timeit.template
的值timeit.template = """
def inner(_it, _timer{init}):
{setup}
_t0 = _timer()
for _i in _it:
retval = {stmt}
_t1 = _timer()
return _t1 - _t0, retval
"""
unutbu's answer适用于python 3.4但不适用于3.5,因为_template_func函数似乎已在3.5中删除
答案 3 :(得分:2)
如果我理解得很好,在python 3.5之后你可以在每个Timer实例定义全局变量而不必在你的代码块中定义它们。我不确定它是否会出现与并行化相同的问题。
我的方法是:
clf = ensemble.RandomForestClassifier(n_estimators=10)
myGlobals = globals()
myGlobals.update({'clf'=clf})
t = Timer(stmt='clf.fit(trainX,trainy)', globals=myGlobals)
print(t.timeit(number=1))
print(clf)
答案 4 :(得分:1)
截至2020年,在ipython或jupyter笔记本中是
t = %timeit -n1 -r1 -o RandomForest(trainX, trainy)
t.best
答案 5 :(得分:0)
我使用它的方法是"追加"运行时间到定时功能的结果。所以,我使用" time"写了一个非常简单的装饰器。模块:
def timed(func):
def func_wrapper(*args, **kwargs):
import time
s = time.clock()
result = func(*args, **kwargs)
e = time.clock()
return result + (e-s,)
return func_wrapper
然后我使用装饰器来实现我想要的功能。
答案 6 :(得分:0)
对于Python 3.X,我使用这种方法:
# Redefining default Timer template to make 'timeit' return
# test's execution timing and the function return value
new_template = """
def inner(_it, _timer{init}):
{setup}
_t0 = _timer()
for _i in _it:
ret_val = {stmt}
_t1 = _timer()
return _t1 - _t0, ret_val
"""
timeit.template = new_template
答案 7 :(得分:0)
在Python 3.5中,globals
已添加到timeit,这使开发人员可以定义在其中运行代码的名称空间。在现有的Python名称空间中运行代码可启用以下timeit语法来计时返回值的函数。
import timeit
print(timeit.timeit("output = your_function(your_params)", number=1, globals = globals()))
它以number
指定的次数打印运行该功能所花费的时间。在示例中,number
参数设置为1。
(0.003316399990580976, 'your_functions ouput')
答案 8 :(得分:0)
如果您不想猴子timeit
补丁,可以尝试使用全局列表,如下所示。这也将在python 2.7中工作,该Python 2.7在globals
中没有timeit()
参数:
from timeit import timeit
import time
# Function to time - plaigiarised from answer above :-)
def foo():
time.sleep(1)
return 42
result = []
print timeit('result.append(foo())', setup='from __main__ import result, foo', number=1)
print result[0]
将先打印时间,然后再打印结果。