前言
GP(Genetic Program) 引入遗传学的概念,从随机初始化第一代种群开始,每一代都要从总体(population_size)中选择适应度(fitness)最好的个体们做父代,通过交叉变异等方式,经过几代(generations)的进化,找到最优个体(program)——适应度最优的个体。
由于它是基于数学的,所以用于自变量与因变量之间存在不易被发现的潜在数学关系的情况。
表示方式
用数学表达式描述自变量和因变量的关系,无确定表达式
y = sub(add(-0.999, X1), mul(sub(X1, X0), add(X0, X1)))
或图表示(图源官网)
import graphviz
构成表达式的运算符
目前支持的函数'add', 'sub', 'mul', 'div', 'sqrt', 'log', 'abs', 'neg', 'inv', 'max', 'min', 'sin', 'cos', 'tan'
可以自定义functions: 自定义运算符,拟合时放进参数function_set参数里就行了:
from gplearn.functions import make_function
或
from gplearn.functions import _Function
eg:
def logic(x1,x2,x3,x4):
return np.where(x1 > x2, x3,x4)
logical = _Function(function=logic,name='logical',arity=4)
#添加到拟合的参数里:
SymbolicRegressor(function_set=('add', 'sub', 'mul', 'div',logical))
评估方式
适应度函数(fitness)
——机器学习中的损失函数
回归中适应度函数默认是mean absolute error,分类中是计算logloss, 所以目标就是最小化fitness
transformer中是使用了相关性,目标是选择与y相关性大的x, 所以目标是最大化fitness
gplearn支持自定义fitness函数:
from gplearn.fitness import make_fitness
遗传算法的计算过程为:
随机初始化得到第一代个体(表达式)们;
根据fitness从第一代所有个体中选择最优的个体们;
进化后得到第二代;
根据fitness选择第二代中最优的个体们;
进化后得到第三代;
……
直到达到fitness的标准或停止标准。
模型
Symbolic Regressor
生成一个预测结果
#进化后的公式用如下代码查看
est = SymbolicRegressor()
est.fit(xtrain, ytrain)
#两种方式计算最优解
print(est)
>>> mul(X7,X8)
print(est._program)
>>> mul(X7,X8)
est._program是最后一代个体里适应度最佳的个体.
est._programs是list of lists, [ [programs1], [programs2], [programs3] ], 展示初代programs至末代programs的全体
'''
查看第generation代的第population个个体
est._programs[generations][population]
'''
# 查看一下末代的第一个个体(不是最优个体)
print(est._programs[-1][0])
SymbolicRegressor 几个关键参数:
crossover、mutation、replace决定最终的个体和初代个体的差别大小,都设为0则最终公式=初代公式
'p_crossover':0.05,
'p_subtree_mutation':0,
'p_hoist_mutation':0,
'p_point_mutation':0,
'p_point_replace':0.03,
数据量小,函数简单,适配小populationsize;
'population_size':1000, #每一代有几个个体(individuals)
'generations':5, #进化了几代
'tournament_size':20, #父代进入子代的数量
'function_set':('add', 'sub', 'mul', 'div', logic),
'metric':'mean absolute error' #适应度
Symbolic Classifier
生成一个预测结果, gplearn目前只支持二分类
fitness和regressor不一样,其他差不多
est = SymbolicClassifier(parsimony_coefficient=.01, generations=3, random_state=1)
est.fit(xtrain, ytrain)
#这两个方法都可以计算最优解,和regressor一样
print(est)
>>> mul(X51, X68)
print(est._program)
>>> mul(X51, X68)
特征生成 Symbolic Transformer
只生成新特征,不生成预测结果
最优个体查看方式是est._best_programs
拟合后需要特征转换,得到新生成的特征:
gp_features = gp.transform(x)
new_diabetes = np.hstack((x, gp_features))
参考
api:
Introduction to GP — gplearn 0.4.2 documentation
code: