使 Hyperopt 与其他编程语言交互
基本有两种方法使 Hyperopt 与其他语言交互
- 你可以为你非 Python 编写的成本函数编写一个 Python 包装器,或者
- 你可以替换
hyperopt-mongo-worker
程序并使用 JSON 直接与 MongoDB 通信。
封装非 Python 代码的调用
使用 Hyperopt 优化非 Python 函数(例如外部可执行文件)参数的最简单方法是围绕该外部可执行文件编写一个 Python 函数包装器。假设你有一个可执行文件 foo
,它接受一个整数命令行参数 --n
并打印出一个分数,你可以这样包装它
import subprocess
def foo_wrapper(n):
# Optional: write out a script for the external executable
# (we just call foo with the argument proposed by hyperopt)
proc = subprocess.Popen(['foo', '--n', n], stdout=subprocess.PIPE)
proc_out, proc_err = proc.communicate()
# <you might have to do some more elaborate parsing of foo's output here>
score = float(proc_out)
return score
当然,要优化 foo
的 n
参数,你还需要调用 hyperopt.fmin 并定义搜索空间。我猜想你会希望这部分在 Python 中完成。
from hyperopt import fmin, hp, rand
best_n = fmin(foo_wrapper, hp.quniform('n', 1, 100, 1), algo=rand.suggest)
print(best_n)
当搜索空间比这里简单的更大时,你可能希望或需要包装函数将其参数转换为外部可执行文件某种类型的配置文件/脚本。
这种方法与 MongoTrials 完全兼容。
直接与 MongoDB 通信
通过直接与 MongoDB 通信,可以更直接地与搜索过程(使用 MongoTrials 时)交互,就像 hyperopt-mongo-worker
所做的那样。解释如何做到这一点超出了本教程的范围,但是 Hannes Schultz (@temporaer) 使 hyperopt 与他的 MDBQ 项目协同工作,MDBQ 是一个独立的基于 MongoDB 的任务队列
查看该代码以及 hyperopt/mongoexp.py 的内容,以了解 worker 进程如何预期在工作队列中预留作业并将结果存储回 MongoDB。