前言
最近在学习YALMIP,跟着官网的Tutorials一步一个脚印地前进着。写的这些关于YALMIP学习的系列文章也都是我从官网翻译过来的,算是给自己的笔记吧。
官网Tutorials链接在此:https://yalmip.github.io/tutorials/.
本文所翻译的Linear programming原文链接在此:https://yalmip.github.io/tutorial/basics/.
线性规划
在此例中,给定两组数据(分别称为蓝组和绿组),我们的目标是利用线性分类器(linear classifier)来给这两组数据分类。
生成随机数据的方法如下:
blues = randn(2,25);
greens = randn(2,25)+2;
% randn()函数可用于产生随机分布的指定均值和方差的矩阵
% 在本例中,两组数据的方差均为1,蓝组的均值为0,绿组的均值为2。
原始数据绘图:
plot(greens(1,:),greens(2,:),'g*')
hold on
plot(blues(1,:),blues(2,:),'b*')
我们希望能利用线性分类器得到一个向量
a
a
a和一个标量
b
b
b,使得所有绿组样本都满足
a
T
x
+
b
≥
0
a^Tx + b \ge 0
aTx+b≥0,而所有蓝组样本都满足
a
T
x
+
b
≤
0
a^Tx + b \le 0
aTx+b≤0(即得到一个分离超平面)。通过对数据的直接观察可得,这是不可能的。因此,我们需要找到一个包含最少分类错误的超平面。一般来说,这是非常困难的组合问题,因此我们可以使用近似值来代替。
引入正数
u
u
u和
v
v
v,并将分类改进为
a
T
x
+
b
≥
1
−
u
a^Tx + b \ge 1 - u
aTx+b≥1−u和
a
T
x
+
b
≤
−
(
1
−
v
)
a^Tx + b \le - (1 - v)
aTx+b≤−(1−v)。如果
u
u
u和
v
v
v的值都很小,分类结果将较好。
定义决策变量方法如下:
a = sdpvar(2,1);
b = sdpvar(1);
欲为每个点使用一个 u u u和一个 v v v变量,我们需要创建两个适当长度的向量。根据下文约束设置的方法,将 u u u和 v v v定义为行向量的原因就不言而喻了。
u = sdpvar(1,25);
v = sdpvar(1,25);
定义如下的分类约束:
Constraints = [a' * greens + b >= 1-u, a' * blues + b <= -(1-v), u >= 0, v >= 0]
根据上文所述,较小的 u u u和 v v v代表了较好的分类结果。因此,目标函数可以建立为最小化所有元素 u u u和 v v v的和。但这是一个病态问题,所以需要添加一个约束,保证 a a a中所有元素的绝对值都小于1,如下所示:
Objective = sum(u)+sum(v)
Constraints = [Constraints, -1 <= a <= 1];
最后,利用optimize()函数求解此问题:
optimize(Constraints,Objective)
利用value函数可以得到 a a a和 b b b的最优解。为了更直观地阐述分类结果,利用YALMIP绘制约束集的能力,对分离超平面进行可视化,方法如下:
x = sdpvar(2,1);
P1 = [-5 <= x <= 5, value(a)' * x + value(b) >= 0];
P2 = [-5 <= x <= 5, value(a)' * x + value(b) <= 0];
clf % clf函数用于清除当前图像窗口
% 利用YALMIP绘制约束集图像,实现分离超平面可视化
plot(P1);
hold on
plot(P2);
% 绘制原始数据图
plot(greens(1,:),greens(2,:),'g*')
plot(blues(1,:),blues(2,:),'b*')
【小贴士:如果上述代码得不出结果,可以进行下列检查:(1)求解器是否正确安装了?(2)是否正确设置路径?(3)求解器的权限是否已过期?】
本节我们学习了线性规划,下一节我们将对二次规划问题及其MATLAB实现方法进行探讨。