# Iris-鸢尾花分类
Iris 数据集是常用的分类实验数据集,由 Fisher, 1936 收集整理。Iris 也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含 150 个数据样本,分为3类,每类 50 个数据,每个数据包含 4 个属性。可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。
Iris 数据集包含了 4 种属性,分别为:
- Sepal.Length (花萼长度);
- Sepal.Width (花萼宽度);
- Petal.Length (花瓣长度);
- Petal.Width (花瓣宽度);
上面四个属性对应三个分类,分别为:
- Iris Setosa (山鸢尾);
- Iris Versicolour (杂色鸢尾);
- Iris Virginica (维吉尼亚鸢尾);
我们并不关注给定的数据到底属于哪个分类,因为数据集已经帮我们做了,所以本实例要做的就是在现有数据的基础之上,基于上述四个属性搜索表达式,最终能够为给定的属性数据划归正确的分类。
# 数据生成
Iris 数据集有专门的 CSV 文件,网上可以很方便找到,这里给出连接:Iris 数据集 (opens new window)。
拿到数据以后,需要对数据做简单处理,我们假定数据已经被处理成了 shape 为 [150, 5] 的数组,由于每条数据的最后一项为所属分类,我们按照机器学习中常用的方式对类别数据进行处理:
- Setosa: [1, 0, 0];
- Versicolour: [0, 1, 0];
- Virginica: [0, 0, 1];
以上处理完成后,每一条数据就变成了 xdata 和 ydata 的映射,例如对于前 3 条数据,其映射结果为:
// 1. [5.1, 3.5, 1.4, 0.2] ==> [1, 0, 0]
// 2. [4.9, 3.0, 1.4, 0.2] ==> [1, 0, 0]
// 3. [4.7, 3.2, 1.3, 0.2] ==> [1, 0, 0]
然后,我们随机打乱所有的数据,然后取出其 2/3 作为训练数据,剩余 1/3 为测试数据。
import IrisData from 'iris.json';
/**
* 对输入数组进行随机排序
* @param indata 输入数组
*/
function createRandomData(indata: number[]) {
let dataCopy = [...indata];
let res: number[] = [];
while(dataCopy.length) {
const idx = Math.floor(Math.random() * dataCopy.length);
res = res.concat(dataCopy.splice(idx, 1));
}
return res;
}
// 打乱原数据
const irisRandomArray = createRandomData(IrisData);
// 训练数据
const trainData = irisRandomArray.slice(0, 100);
// 测试数据
const testData = irisRandomArray.slice(100);
# 输入参数
模型接收 4 个入参,对应数据集中的四个属性。
符号 | 类型 | 说明 | 属性 |
---|---|---|---|
a | Number | Sepal.Length | 花萼长度 |
b | Number | Sepal.Width | 花萼宽度 |
c | Number | Petal.Length | 花瓣长度 |
d | Number | Sepal.Width | 花瓣宽度 |
# 集合算子
符号 | 表达式 |
---|---|
+ | a + b |
- | a - b |
* | a * b |
/ | a / b |
E | 常数 E |
Q | sqrt |
S | sin |
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('Q', Math.sqrt);
operators.setFunc('S', Math.sign);
operators.setFunc('L', Math.log);
// 设置入参变量
operators.setVars('a');
operators.setVars('b');
operators.setVars('c');
operators.setVars('d');
// 导出数组以便环境使用
const operSets = operators.toArray();
# 环境参数:
头部长度 | 突变率 | 混入率 | 修正因子 |
---|---|---|---|
5 | 0.3 | 0.3 | 0.0001 |
# 遗传参数
由于环境参数中基因的头部长度只有 3 ,显的非常短,为了确保整个基因能顺利表达出系数 k ,我们将 Gene shape 设置为 [1, 5] ,这样可以增加基因的长度,有助于表达系数。
种群 | 染色体长度 | Gene Shape | 损失函数 | 激活函数 | 迭代数 |
---|---|---|---|---|---|
50 | 3 | [1, 5] | Loss.categorical_disc | Activation.tanh | 500 |
# 可视化
点击下方开始按钮查看训练过程。
下方的三个统计图分别记录了 训练数据误差、 测试数据误差 和 测试数据的回测准确率 。
表达式:
Click the "Start" button to start calculating the expression
点击下方按钮开始执行
← 波士顿房价预测