I'm currently trying to implement the following algorithm for finding max.-margin decision boundaries (for use in an SVM):
let D = {(x1, y1), (x2, y2), . . . , (xl, yl )} ⊂ Rn ×{+1,−1}
r ← max{|x| | (x, y) ∈ D}
q ← 1000
let w∗ and b∗ be undefined
Construct X according to (6.32) using D.
for each b ∈ [−q, q] do
Construct c according to (6.33) using b.
w ← solve(I, 0, X, c)
if (w is defined and w∗ is undefined) or (w is defined and |w| < |w∗|) then
w∗ ← w
b∗ ← b
end if
end for
if w∗ is undefined then
stop constraints not satisfiable
else if |w|∗ > q/r then
stop bounding assumption of |w| violated
end if
return (w∗, b∗)
The only variable we're concerned about is w*, which is supposed to be a matrix (from the package CVXOPT, not a numpy array -- although CVXOPT matrices can be created from numpy arrays). The main problem happens when I check whether w* is defined.
If I initialize it to None on line 4, then it works fine for the "w* is undefined" comparison in line 9, but the second comparison "|w| < |w*|", which compares the norm of w and w*, fails since you can't just run np.linalg.norm() on a None variable.
If I initialize w* to some junk matrix (say [40,40]) and remember that as my placeholder value for undefined, substituting in that junk matrix down the line where I need to check if w* is undefined, then I also run into problems -- CVXOPT won't allow for direct comparison of matrices to see if they're equal or not. I could cycle through and compare each element, but that would hurt performance significantly (esp. since I may use this for large datasets).
Here's my a Gist with my faulty code: http://tinyurl.com/pr5j44w
Note that wopt is the problematic variable w*.
Change your test; rather than
var_defined(wopt)
, usewopt is not None
. Python's lazyand
/or
evaluation will then mean that thenp.linalg
is only applied ifwopt
has been defined.Your current
var_defined
function is useless; if a name actually hasn't been assigned, you will get aNameError
when you try to call the function on that name. Within the function, if it does get called without error,var
is always defined (as it is the argument), so it will alwaysreturn 1
. You aren't actually checking whether the argumentis None
.Also, functions like that should
return
True
orFalse
rather than0
and1
, and can be tested directly: