符号回归与LaTeX公式

前文讲到,gplearn支持导出dot语言脚本,进而可以利用graphviz画图。本文将要尝试实现,将gplearn生成的公式转换成人类可读格式。

公式转换流程

公式转换流程图
1: 公式转换流程图

本文所介绍的公式转换流程如1所示。

需要下载安装的Python

  • requests
  • sympy

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。 URLhttps://mathjax.cerallin.top/?latex=E%3Dmc^2

结合gplearn使用

按照1所示流程,代码可以分成三部分。

  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, tan

# 转换成人类可读的公式
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,
'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)
  1. SymPy -> LaTeX
1
2
# 转换成LaTeX公式
formula_latex = sympy.latex(formula)
  1. LaTeX -> SVG
1
2
3
4
5
6
7
8
9
10
11
# 根据LaTeX公式转换成SVG图片
import requests

svg_res = requests.get('https://mathjax.cerallin.top/', {
'latex': formula_latex
}).text

# 输出SVG图片到文件
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.

0条搜索结果。