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