之前无聊做了个简单的Python智能算法库的小总结:Python智能优化算法库小汇总 。当时没注意到有一个库PySwarms是基于另外一个小库 PySwarm开发的。
这个库非常有意思,整个库只依赖Numpy,并且最核心的文件其实只有一个:pso.py.
简介里面写着:pso that supports constraints. 并且还有200个stars.
这么有趣的库我们当然要来玩一玩。于是开干:
先来个最简单的无约束优化
目标函数就取一个最简单的二次函数:
简单跑一下看看效果。这个问题很显然解析解就是所有变量为0,它的结果是10的负5次方量级,基本上算是对的。误差我们用的是默认值,迭代次数也不多,还行。
再来试试它标榜的带约束优化
这个问题整得稍复杂一点,它的最优值是 x1等于6,x2等于4.9999,目标函数的最小值是11。(注意,这里说的就是精确值)。
跑完之后看看效果。几乎和解析解一样,误差很小。这个效果还是挺不错的。
针对这个问题我们还要简单解释一下,它的约束条件的定义其实非常简单。写成标准函数就是 g(x)大于等于0。在咱们这个例子里由于它是一个线性函数,所以我们就直接列出它的系数矩阵。这种定义方式非常方便,因为只要是 可计算 的函数都可以写出来。
上面这些问题都还比较简单,但在实际问题中我们更想玩的一类问题是,带有参数的优化问题。
比如我们先考虑一下这个非常简单的问题。目标函数仍然是一个二次函数,但每个分量的前面都有个系数。
这个语法也很简单,先定义一个带有两个参数的函数。再把参数值写成一个dict
放在外面,最后把它传给pso
函数即可。运行之后我们可以看到这个效果还是不错的,也是在10的负5次方量级。
这种带参数的优化算法就忍不住让人玩一把函数拟合
咱们来考虑这个非常简单的线性函数。目标函数设成均方误差。那么这里 xi, yi 组成的样本集就是我们要传的参数。
为了方便起见我们先让 x 在1到10取值,取100个点。为了让难度增大一点我们在生成 y的时候加上5%的噪声。最后把它们放到一个dict
里面。
为了更方便,我们改变一下目标函数的定义,直接用**kwargs
作为参数,这样我们就可以省略掉在函数中重新对变量进行提取命名的过程。 直接调用x,y就可以了。返回值就是最小均方误差。
寻优范围我们设成负5到正5。一切就绪开干看结果。 注意咱们生成数据时的模型里a等于0.1,b等于2。由PSO算出的结果分别是0.1043和1.9734。由于加了5%的噪声,出现了一点偏差,这是非常正常的。而最后的均方误差也只有0.531。效果还是很不错的。
为了更直观地看到效果咱还是把对比图画一下。由于我们给的系数比较小,所以加了5%的噪声过后还是能看到很明显的波动。不过拟合出的这条直线看起来是很好地穿过了它们的中间,效果是不错的。如果噪声再小一点可能还会更好。
当然,这个库似乎也并不完美
目前感觉毛病还挺多,比如不能在API关闭verbose
,没有返回迭代过程(收敛曲线的值)等等。但整个设计很完整,运行也很稳定。所以还是可以玩一玩的。
另外,目前我们仍然觉得Python的智能算法库还不够多,不够丰富。希望今后能有更多更好的库出现吧。
今天就到这里,谢谢大家!~