以下我们讨论第三步,也是GEP中最为控制性的一步。如何设置适应性函数。
同样首先定义一些标准接口:
/**
* 适应度函数 根据训练数据的所有值, 计算适应度函数
*/
public interface Fitness
{
/**
* 返回该适应度函数返回的最小适应度值 (作为死基因的染色体适应度值)
* @return
*/
double getMinFitness();
}
**
* 数值的适应度函数
*/
public interface NFitness:Fitness
{
/**
* 由模型预测值计算适应度函数
* @param predicates
* @return
*/
public abstract double calculate(double[] values);
}
以下是一种通用适应度函数与两种适应度函数的类。
/**
* 通用适应度函数
*/
public abstract class GeneralNFitness :NFitness
{
protected double[] targets; // 样本的目标值
protected GeneralNFitness(NDataSet dataSet)
{
this.targets = dataSet.getTargets();
}
}
/**
* 使用绝对误差计算适应度函数
*/
public class AbsoluteErrorFitness :GeneralNFitness
{
private final double MIN_FITNESS = 1.0;
private double[] targets; // 目标值
private double M; // 允许的绝对误差值上限
public AbsoluteErrorFitness(NDataSet dataSet, double M)
{
this.targets = dataSet.getTargets();
}
public double calculate(double[] values)
{
double sum = 0.0;
for (int i=0; i<values.length; i++)
{
sum += M - Math.abs(values[i]-targets[i]);
}
if (sum<0) sum = 0;
return sum;
}
public double getMinFitness()
{
return MIN_FITNESS;
}
public String toString()
{
return this.Tostring()+ "(M:" + M +")";
}
}
/**
* 使用复相关系数的适应度函数
*/
public class CorrelationCoefficientFitness : GeneralNFitness
{
private static double MIN_FITNESS = -100;
private double deviation; // 目标数据的偏差
public CorrelationCoefficientFitness(NDataSet dataSet)
{
this.targets = dataSet.getTargets();
}
/**
* 初始化 计算目标值的偏差
*/
private void initialize()
{
int size = targets.length;
double average = 0.0;
for (int i=0; i<size; i++)
{
average += targets[i];
}
average /= size;
deviation = 0.0;
for (int i=0; i<size; i++)
{
double t = targets[i] - average;
deviation += t * t;
}
}
public double calculate(double[] values)
{
double f = 0.0;
for (int i=0; i<values.length; i++)
{
double t = values[i] - targets[i];
f += t * t;
}
f = 1 - f/deviation;
if (f<MIN_FITNESS) f = MIN_FITNESS;
return f;
}
/**
* 使用相对误差的适应度函数
*/
public class RelativeErrorFitness : GeneralNFitness
{
private double MIN_FITNESS = 1.0;
private double M; // 允许的最大相对误差上限
public RelativeErrorFitness(NDataSet dataSet, double M)
{
this.targets = dataSet.getTargets();
}
public double calculate(double[] values)
{
int size = targets.length;
double fitness = 0.0;
for (int i=0; i<size; i++)
{
fitness += M - Math.abs((values[i]-targets[i])/targets[i]*100);
}
if (fitness<MIN_FITNESS) fitness = MIN_FITNESS;
return fitness;
}
public double getMinFitness()
{
return MIN_FITNESS;
}
public String toString()
{
return this.Tostring()+ "(M:" + M +")";
}
}
以上是两种常用的适应度函数。