前文 讲到,gplearn 支持导出 dot 语言脚本,进而可以利用 graphviz 画图。本文将要尝试实现,将 gplearn 生成的公式转换成人类可读格式。
公式转换流程 图 1: 公式转换流程图 本文所介绍的公式转换流程如图 1 所示。
需要下载安装的 Python 库 SymPy 18 年的 stackoverflow 回答 给出了一种解决方案:使用 SymPy 进行公式转换。
1 2 3 4 5 6 7 8 9 10 converter = { 'sub' : lambda x, y : x - y, 'div' : lambda x, y : x/y, 'mul' : lambda x, y : x*y, 'add' : lambda x, y : x + y, 'neg' : lambda x : -x, 'pow' : lambda x, y : x**y } sympy.sympify('sqrt(div(add(1.000, X0), mul(-0.993, X0)))' , locals =converter)
上述代码将公式转换成 sympy 的内部格式,然后使用sympy.latex
就可以输出 LaTeX 公式了。
LaTeX 公式在线转换 API LaTeX 公式也不是非常直观,为了将其转换为 SVG 格式图片,我写出并部署了一个基于 MathJax 的在线转换 API。 URL 为https://mathjax.cerallin.top/?latex=E%3Dmc^2
。
结合 gplearn 使用 按照图 1 所示流程,代码可以分成三部分。
gplearn -> SymPy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from sympy import sqrt, log, abs , max , min , sin, cos, tanconverter = { 'sub' : lambda x, y: x - y, 'div' : lambda x, y: x / y, 'mul' : lambda x, y: x * y, 'add' : lambda x, y: x + y, 'sqrt' : lambda x : sqrt(x), 'log' : lambda x : log(x), 'abs' : lambda x : abs (x), 'neg' : lambda x : -x, 'inv' : lambda x : 1 / x, 'max' : lambda x, y: max (x, y), 'min' : lambda x, y: min (x, y), 'sin' : lambda x : sin(x), 'cos' : lambda x : cos(x), 'tan' : lambda x : tan(x), } formula = sympy.sympify(str (est_gp._program), locals =converter)
SymPy -> LaTeX 1 2 formula_latex = sympy.latex(formula)
LaTeX -> SVG 1 2 3 4 5 6 7 8 9 10 11 import requestssvg_res = requests.get('https://mathjax.cerallin.top/' , { 'latex' : formula_latex }).text with open ('SymbolicRegressor' +'.svg' , "w" , encoding='utf-8' ) as f: f.write("%s" % svg_res) f.close()
结果展示 gplearn 输出结果 gplearn 预测的符号树 SymPy 公式 1 X3 + (X2 + X5)*(X0*X1*X5 + X1) + 43.151
LaTeX 公式 1 2 3 $ $ X_ {3} + \left (X_ {2} + X_ {5}\right ) \left (X_ {0} X_ {1} X_ {5} + X_ {1}\right ) + 43.151 $ $
SVG 图片 根据 LaTeX 公式生成的 SVG 图片 Fin.