# 非线性拟合
与线性回归的建议不同,非线性回归可以使用任何算子,只要包含了非线性算子,那么拟合结果就有很大可能是非线性的。
# 数据生成
在本节示例中,测试数据由下面的函数生成:
// 随机生成系数 a, b 和常量 c
const a = (Math.random() - 0.5) * 4.13 + 1
const b = Math.random() * 6.18 / Math.sin(Math.random() + Math.PI / 2);
const c = Math.random() * 1.2345;
// f(x):
const y = a * x * x + b * x + c + Math.random() * noise;
上述生成规则的系数并非只能取 6.18 或 4.13 ,这完全可以由随机数决定,只是为了表达式方便观察,特意取了 3.14 和 0.618 的反序。
# 输入参数
模型接收一个 x
作为入参 终止符。
符号 | 类型 | 说明 |
---|---|---|
x | Number | X轴坐标 |
# 集合算子
除基本算子外,增加 Q
、 P
和 L
作为非线性算子,辅助非线性表达。
符号 | 表达式 |
---|---|
+ | a + b |
- | a - b |
* | a * b |
/ | a / b |
H | a / 2 |
T | a / 3 |
E | 常数 E |
Q | sqrt |
P | pow |
L | log |
使用 Operator 模块设置入参和算子:
import { Operator } from 'gepjs';
const operators = new Operator();
// 清空内建算子
operators.clear();
// 设置新算子
operators.setFunc('+', (a, b) => a + b);
operators.setFunc('-', (a, b) => a - b);
operators.setFunc('*', (a, b) => a * b);
operators.setFunc('/', (a, b) => a / b);
operators.setFunc('H', (a) => a / 2);
operators.setFunc('T', (a) => a / 3);
operators.setFunc('E', () => Math.E);
operators.setFunc('P', Math.pow);
operators.setFunc('Q', Math.sqrt);
operators.setFunc('L', Math.log);
// 设置入参变量
operators.setVars('x');
// 导出数组以便环境使用
const operSets = operators.toArray();
# 环境参数
基因表达非线性结果时,可以适当加长头部,本示例将头部长度设置为 5 。
头部长度 | 突变率 | 混入率 | 修正因子 |
---|---|---|---|
5 | 0.3 | 0.3 | 0.001 |
# 遗传参数
为了能增强系数表达和发现,将基因长度适当加长,本示例的 Gene shape 为 [1, 5] 。
种群 | 染色体长度 | Gene Shape | 损失函数 | 迭代数 |
---|---|---|---|---|
50 | 1 | [1, 5] | Loss.absolute_mean | 500 |
# 可视化
点击下方开始按钮查看动态拟合过程。
表达式:
Click the "Start" button to start calculating the expression
点击下方按钮开始执行