blob: d9ecfb5fe6aac7060d738ee3640ae8420a756bbf [file] [log] [blame]
Austin Schuh9049e202022-02-20 17:34:16 -08001Support vector machine (SVM)
2============================
3
4*Support vector machine* seeks an affine function that approximately classifies the two sets of points.
5The problem can be stated as
6
7.. math::
8 \begin{array}{ll}
9 \mbox{minimize} & \frac{1}{2} x^T x + \gamma \sum_{i=1}^{m} \max(0, b_i a_i^T x + 1),
10 \end{array}
11
12where :math:`b_i \in \{ -1, +1 \}` is a set label, and :math:`a_i` is a vector of features for the :math:`i`-th point.
13The problem has the following equivalent form
14
15.. math::
16 \begin{array}{ll}
17 \mbox{minimize} & \frac{1}{2} x^T x + \gamma \boldsymbol{1}^T t \\
18 \mbox{subject to} & t \ge {\rm diag}(b) Ax + 1 \\
19 & t \ge 0,
20 \end{array}
21
22where :math:`{\rm diag}(b)` denotes the diagonal matrix with elements of :math:`b` on its diagonal.
23
24
25
26Python
27------
28
29.. code:: python
30
31 import osqp
32 import numpy as np
33 import scipy as sp
34 from scipy import sparse
35
36 # Generate problem data
37 sp.random.seed(1)
38 n = 10
39 m = 1000
40 N = int(m / 2)
41 gamma = 1.0
42 b = np.hstack([np.ones(N), -np.ones(N)])
43 A_upp = sparse.random(N, n, density=0.5)
44 A_low = sparse.random(N, n, density=0.5)
45 Ad = sparse.vstack([
46 A_upp / np.sqrt(n) + (A_upp != 0.).astype(float) / n,
47 A_low / np.sqrt(n) - (A_low != 0.).astype(float) / n
48 ], format='csc')
49
50 # OSQP data
51 Im = sparse.eye(m)
52 P = sparse.block_diag([sparse.eye(n), sparse.csc_matrix((m, m))], format='csc')
53 q = np.hstack([np.zeros(n), gamma*np.ones(m)])
54 A = sparse.vstack([
55 sparse.hstack([sparse.diags(b).dot(Ad), -Im]),
56 sparse.hstack([sparse.csc_matrix((m, n)), Im])
57 ], format='csc')
58 l = np.hstack([-np.inf*np.ones(m), np.zeros(m)])
59 u = np.hstack([-np.ones(m), np.inf*np.ones(m)])
60
61 # Create an OSQP object
62 prob = osqp.OSQP()
63
64 # Setup workspace
65 prob.setup(P, q, A, l, u)
66
67 # Solve problem
68 res = prob.solve()
69
70
71Matlab
72------
73
74.. code:: matlab
75
76 % Generate problem data
77 rng(1)
78 n = 10;
79 m = 1000;
80 N = ceil(m/2);
81 gamma = 1;
82 A_upp = sprandn(N, n, 0.5);
83 A_low = sprandn(N, n, 0.5);
84 Ad = [A_upp / sqrt(n) + (A_upp ~= 0) / n;
85 A_low / sqrt(n) - (A_low ~= 0) / n];
86 b = [ones(N, 1); -ones(N,1)];
87
88 % OSQP data
89 P = blkdiag(speye(n), sparse(m, m));
90 q = [zeros(n,1); gamma*ones(m,1)];
91 A = [diag(b)*Ad, -speye(m);
92 sparse(m, n), speye(m)];
93 l = [-inf*ones(m, 1); zeros(m, 1)];
94 u = [-ones(m, 1); inf*ones(m, 1)];
95
96 % Create an OSQP object
97 prob = osqp;
98
99 % Setup workspace
100 prob.setup(P, q, A, l, u);
101
102 % Solve problem
103 res = prob.solve();
104
105
106
107CVXPY
108-----
109
110.. code:: python
111
112 from cvxpy import *
113 import numpy as np
114 import scipy as sp
115 from scipy import sparse
116
117 # Generate problem data
118 sp.random.seed(1)
119 n = 10
120 m = 1000
121 N = int(m / 2)
122 gamma = 1.0
123 b = np.hstack([np.ones(N), -np.ones(N)])
124 A_upp = sparse.random(N, n, density=0.5)
125 A_low = sparse.random(N, n, density=0.5)
126 A = sparse.vstack([
127 A_upp / np.sqrt(n) + (A_upp != 0.).astype(float) / n,
128 A_low / np.sqrt(n) - (A_low != 0.).astype(float) / n
129 ], format='csc')
130
131 # Define problem
132 x = Variable(n)
133 objective = 0.5*sum_squares(x) + gamma*sum(pos(diag(b)*A*x + 1))
134
135 # Solve with OSQP
136 Problem(Minimize(objective)).solve(solver=OSQP)
137
138
139
140
141YALMIP
142------
143
144.. code:: matlab
145
146 % Generate problem data
147 rng(1)
148 n = 10;
149 m = 1000;
150 N = ceil(m/2);
151 gamma = 1;
152 A_upp = sprandn(N, n, 0.5);
153 A_low = sprandn(N, n, 0.5);
154 A = [A_upp / sqrt(n) + (A_upp ~= 0) / n;
155 A_low / sqrt(n) - (A_low ~= 0) / n];
156 b = [ones(N, 1); -ones(N,1)];
157
158 % Define problem
159 x = sdpvar(n, 1);
160 objective = 0.5*norm(x)^2 + gamma*sum(max(diag(b)*A*x + 1, 0));
161
162 % Solve with OSQP
163 options = sdpsettings('solver','osqp');
164 optimize([],objective,options);
165