纯 Python 实现的符号回归,仅用 8 个数据点就重新发现了开普勒定律。
Pure-Python symbolic regression that rediscovered Kepler's law from 8 data point

原始链接: https://github.com/ariel95500-create/gp-elite

GP_ELITE 是一个纯 Python 库,专为符号回归而设计,旨在将实验数据转化为可解释的数学定律,而非“黑箱”模型。它针对工程、物理及传感器校准中常见的小型、含噪数据集(最多 20 个变量,100–5000 个数据点)进行了专门优化。 **主要特性:** * **易于使用:** 只需 `pip install` 即可安装,无需 Julia 或 GPU 等复杂依赖。提供用于处理 CSV 文件的简易控制台界面,以及适用于笔记本环境的灵活 API。 * **高性能:** 具备 Levenberg–Marquardt 常数优化功能,可实现接近机器精度的运算,并配有稳健的回归模式以处理异常值。 * **可靠性:** 内置过拟合保护(留出法验证)和帕累托前沿选择,使用户能够在公式的复杂度和准确性之间取得平衡。 * **验证成果:** 已成功复现物理定律(如开普勒第三定律),在符号回归基准测试中表现优于传统工具。 GP_ELITE 是工程师和科学家的理想选择,擅长寻找符合物理逻辑的关系(如电池衰减曲线),在可解释性重于暴力预测能力的场景下表现卓越。该库采用开源(MIT 许可证)且高度可复现,为数据驱动的发现提供了零门槛的解决方案。

一位开发者发布了 **GP_ELITE**,这是一个纯 Python 编写的符号回归引擎,旨在从小型数据集(100 至 5,000 个数据点)中发现可读的数学公式。与黑盒机器学习模型不同,GP_ELITE 能识别出控制数据的底层方程。为进行演示,该工具仅用八个行星数据点,在大约三秒内成功重新发现了开普勒第三定律。 其主要功能包括用于高精度常数拟合的列文伯格-马夸特(Levenberg-Marquardt)优化、用于模型选择的帕累托前沿(Pareto front)输出,以及一种“受控”预测模式。在基准测试中,它的表现优于现有的 `gplearn` 库,能更准确地恢复物理方程。 虽然创建者指出该工具并非为大规模机器学习或混沌数据而设计,但它为 PySR 等通常需要 Julia 或 C++ 工具链的最先进工具提供了一种“零门槛”的替代方案。在讨论工具的局限性时,作者承认符号恢复仍对噪声敏感,并指出尽管拟合质量会平稳下降,但发现“真实”的底层公式目前仍是整个符号回归领域面临的主要挑战。
相关文章

原文

Genetic-programming symbolic regression — discover interpretable laws from your experimental data.

🇫🇷 Version française

GP_ELITE searches for a mathematical formula linking your variables to a target, instead of a black box. It is built for small experimental datasets (≤10 variables, 100–5000 points) where you want to understand the relationship: degradation laws, sensor calibration, engineering correlations, dose–response curves, physical laws.

Pure Python / NumPy — no Julia, no compilation, no GPU. pip install and you're ready.

GP_ELITE rediscovers Kepler's Third Law from 8 data points (R² = 1.000000)

Given only the 8 planets' distance and orbital period, GP_ELITE rediscovered Kepler's Third Law (T = a·√a = a^1.5) in seconds — see examples/kepler_demo.py.

from gp_elite import symbolic_regression

result = symbolic_regression(X, y, feature_names=["cycle", "temperature", "current"])
print(result.expression)        # capacity_SOH = 0.913 - 0.352·tanh(...)
print(result.r2_validation)     # 0.996  (on data never seen during training)

  • Levenberg–Marquardt constant fitting (default): constants reach machine precision — Coulomb's q1·q2/(4πεr²) recovered exactly (1−R² ≈ 8e-32). 6–14× faster on constant-heavy problems.
  • Multi-restart reliability (restarts=N): independent runs share one deterministic hold-out, their candidate archives are merged, and one global selection is made.
  • Pareto front output (result.pareto): the full complexity ↔ accuracy staircase, each entry with its own .predict.
  • Forecast / extrapolation mode (extrapolate_feature=, extrapolate_direction=): out-of-domain divergence probes, a linear safety floor, frontier-based selection. Also available as mode 7 in the interactive menu.
  • Reproducibility: identical results per seed within a process; across invocations, run with PYTHONHASHSEED=0.

GP_ELITE Neural networks PySR (state of the art)
Output readable formula black box readable formula
Installation pip install (pure Python) heavy requires Julia
Overfitting guard built-in (hold-out) do it yourself do it yourself
Variable selection importance report no partial

GP_ELITE's niche: zero barrier to entry. A lab engineer, a student, or a technician points at a CSV file and gets a validated law back — without becoming a developer.


pip install gp-elite          # from PyPI
# or, from source:
git clone https://github.com/ariel95500-create/gp-elite
cd gp-elite && pip install -e .

Dependencies: numpy, pandas, scikit-learn.


One line, on your own data (console UI)

Choose mode 6 (generic CSV), point to your file, and keep the defaults. GP_ELITE detects the columns, holds out a validation set, evolves, and prints the discovered law with its generalization report.

Programmatically (notebooks, pipelines)

import numpy as np
from gp_elite import symbolic_regression

X = np.random.uniform(1, 5, (200, 2))
y = 2.0 + 3.0 * np.sqrt(X[:, 0]) - 0.5 * X[:, 1]

result = symbolic_regression(
    X, y,
    feature_names=["a", "b"],
    operators="physical",   # 'physical' | 'trig' | 'full' | 'poly'
    generations=60,
    speed="fast",           # 'ultrafast' | 'fast' | 'normal'
)

print(result.expression)        # e.g. 2.0 + 3.0·sqrt(a) - 0.5·b
print(result.r2_validation)     # quality on the hold-out set
print(result.size)              # node count (readability)

🛡️ Robust regression (outlier-resistant custom loss)

Real-world data is dirty. A handful of outliers can drag an ordinary least-squares fit far from the true relationship. GP_ELITE ships a one-switch robust mode that fits the true law even when a sizeable fraction of the data is corrupted.

from gp_elite import symbolic_regression

# X, y : your (possibly dirty) data
result = symbolic_regression(X, y, feature_names=["x"], robust=True)
print(result.expression)

Under the hood, robust=True switches the objective to a Huber loss and rescales the final coefficients with an IRLS (Iteratively Reweighted Least Squares) procedure, so the fit is governed by the bulk of the data rather than by a few extreme points. It stays a compact, readable formula.

Measured behaviour (recovering y = 2x + 1 — RMSE against the true law on clean points, lower is better):

outliers MSE (default) robust=True
0 % 0.063 0.063
10 % 1.398 1.374
20 % 1.925 0.543

With clean data, ordinary MSE wins by a hair — robustness isn't free. With 10–20 % outliers, robust mode recovers the true law while plain MSE derails. Use robust=True when you suspect your data contains outliers.

See examples/robust_regression.py for the full reproducible benchmark.


Full example: battery degradation (NASA data)

python examples/battery_soh.py

From 168 real charge cycles, GP_ELITE discovers a state-of-health (SOH) law:

capacity_SOH ≈ 0.913 − 0.352 · tanh( cycle^((temperature/cycle)^0.485) )

R² validation = 0.996   (on cycles never seen)   12 nodes

A saturating degradation with cycle count, modulated by temperature — physically plausible, and certified on unseen data.


What is GP_ELITE good (and less good) at?

Good at: physical / engineering laws with multiplicative or exponential structure, modest-size noisy experimental data, problems where interpretability matters most.

On the frozen Feynman benchmark (15 physics equations, PYTHONHASHSEED=0, restarts=4): 10/15 exact symbolic recoveries (67%) at machine precision (1−R² < 1e-9), 14/15 within 1e-3 (93%). Head-to-head against gplearn on identical data/splits (generous budget for gplearn): 67% vs 40% exact — GP_ELITE ahead on 9 equations, tied on 5, behind on 1. Real-data forecasting (NASA battery SOH, true extrapolation on unseen cycles): median R² +0.52 vs +0.34 for linear regression, with zero divergent models. Reproduce: PYTHONHASHSEED=0 python benchmarks/feynman_bench.py 0 15 and benchmarks/duel.py.

Less good at: chaotic sequences (e.g. Collatz flight time — an intrinsically random component), >15–20 variables (the search space explodes), large datasets where raw accuracy outweighs interpretability (ensemble models dominate there).


  • Levenberg–Marquardt constant optimization (v0.2): closed-form-quality constants, deterministic, LM/Adam switchable
  • Multi-restart + merged candidate archives (v0.2): seed variance turned into reliability
  • Pareto front API (v0.2): non-dominated complexity/accuracy staircase
  • Guarded extrapolation / forecasting mode (v0.2): beyond-domain probes, linear floor, frontier selection
  • Composition motif seeding (v0.2): Pythagorean, reciprocal-sum, Gaussian templates for nested structures
  • Asymmetric island model (explorer / cleaner / stigmergic) with periodic migration
  • Linear scaling (Keijzer 2003): the engine searches for the shape; scale and offset coefficients are solved in closed form
  • ε-lexicase selection (La Cava 2016) to preserve behavioral diversity
  • Island parallelism (multi-core) — ≈ ×3 measured on 4 cores
  • Hold-out validation + parsimonious champion selection (R² tolerance): built-in overfitting guard
  • Shift-free normalization preserving multiplicative structure (x·y stays a clean product)
  • Transferable stigmergic memory across runs (grammar export/import)

pip install pytest
pytest -q

MIT — see LICENSE. Free to use, including commercially, with retention of the copyright notice.

If GP_ELITE is useful in academic work, see CITATION.cff.

联系我们 contact @ memedata.com