3

My first question so please bear with me :)

I use the Shogun toolbox to work with SVM in Python. I just experiment first to get a better understanding of SVM's. I wrote something in Python with some data points to linearly separate. I use the LibSVM()

X = np.array([[2.0,  2.0, 1.0, 1.0],               
              [1.0, -1.0, 1.0, -1.0]])

Y = np.array([[4.0, 5.0,  5.0, 4.0],
              [1.0, 1.0, -1.0, -1.0]])

sample data points

After training the SVM with the given data I can retrieve its bias(get_bias()), the support vectors(get_support_vectors()) and other properties. What I can't get done is plotting the line/hyperplane. I know the equation for the hyperplane is y=wx + b but how to write/plot this down to see it in my figure.

2 Answers 2

1

for a complete example

enter image description here

import numpy as np
import matplotlib.pyplot as plt

def __intersect(rect, line):
    l = []
    xmin,xmax,ymin,ymax = rect
    a,b,c = line

    assert a!=0 or b!=0

    if a == 0:
        y = -c/b
        if y<=ymax and y>=ymin:
            l.append((xmin, y))
            l.append((xmax, y))
        return l
    if b == 0:
        x = -c/a
        if x<=xmax and x>=xmin:
            l.append((x, ymin))
            l.append((x, ymax))
        return l

    k = -a/b
    m = -c/b
    for x in (xmin, xmax):
        y = k*x+m
        if y<=ymax and y>= ymin:
            l.append((x,y))

    k = -b/a
    m = -c/a
    for y in (ymin, ymax):
        x = k*y+m
        if x<xmax and x> xmin:
            l.append((x,y))
    return l


def plotline(coef, *args, **kwargs):
    '''plot line: y=a*x+b or a*x+b*y+c=0'''
    coef = np.float64(coef[:])
    assert len(coef)==2 or len(coef)==3
    if len(coef) == 2:
        a, b, c = coef[0], -1., coef[1]
    elif len(coef) == 3:
        a, b, c = coef
    ax = plt.gca()

    limits = ax.axis()
    points = __intersect(limits, (a,b,c))
    if len(points) == 2:
        pts = np.array(points)
        ax.plot(pts[:,0], pts[:,1], *args, **kwargs)
        ax.axis(limits)

def circle_out(x, y, s=20, *args, **kwargs):
    '''Circle out points with size 's' and edgecolors'''
    ax = plt.gca()
    if 'edgecolors' not in kwargs:
        kwargs['edgecolors'] = 'g'
    ax.scatter(x, y, s, facecolors='none', *args, **kwargs)


def plotSVM(coef, support_vectors=None):
    coef1 = coef[:]
    coef2 = coef[:]
    coef1[2] += 1 
    coef2[2] -= 1
    plotline(coef, 'b', lw=2)
    plotline(coef1, 'b', ls='dashed')
    plotline(coef2, 'b', ls='dashed')

    if support_vectors != None:
        circle_out(support_vectors[:,0], support_vectors[:,1], s=100)


from pylab import *

X = array([[2.0,  2.0, 1.0, 1.0],               
              [1.0, -1.0, 1.0, -1.0]])

Y = array([[4.0, 5.0,  5.0, 4.0],
              [1.0, 1.0, -1.0, -1.0]])

data = hstack((X,Y)).T
label = hstack((zeros(X.shape[1]), ones(Y.shape[1])))

from sklearn.svm import SVC

clf = SVC(kernel='linear')
clf.fit(data, label)

coef = [clf.coef_[0,0], clf.coef_[0,1], clf.intercept_[0]]
scatter(data[:,0], data[:,1], c=label)
plotSVM(coef, clf.support_vectors_)
show()
Sign up to request clarification or add additional context in comments.

3 Comments

First, thank you for a complete example. But the implementation is done with sklearn which is not the module I'm working with. I'm working with shogun and use the class LibSVM. So I looked at the given example but I can't figure out what clf.coef_ means in terms of the properties of LibSVM. After training we have the alphas libsvm.get_alphas() and can get the w out of that by sum(alpha*label*support_vector). I'm sorry if I wasn't clear the first time, but I really try to understand SVM by reproducing the numbers/vectors etc.
So my question is: how to plot the hyperplane, working with shogun :)
That's a good example code... I'm curious why you use this hstack function as the output of hstack array of arrays, and array with 0/1 can be set as parameters of SVC directly.
0
from pylab import *

def __intersect(rect, line):
    l = []
    xmin,xmax,ymin,ymax = rect
    a,b,c = line

    assert a!=0 or b!=0

    if a == 0:
        y = -c/b
        if y<=ymax and y>=ymin:
            l.append((xmin, y))
            l.append((xmax, y))
        return l
    if b == 0:
        x = -c/a
        if x<=xmax and x>=xmin:
            l.append((x, ymin))
            l.append((x, ymax))
        return l

    k = -a/b
    m = -c/b
    for x in (xmin, xmax):
        y = k*x+m
        if y<=ymax and y>= ymin:
            l.append((x,y))

    k = -b/a
    m = -c/a
    for y in (ymin, ymax):
        x = k*y+m
        if x<=xmax and y>= xmin and len(l) < 2:
            l.append((x,y))
    return l


def plotLine(coef, *args, **kwargs):
    '''plot line: y=a*x+b or a*x+b*y+c=0'''
    coef = float64(coef[:])
    assert len(coef)==2 or len(coef)==3
    if len(coef) == 2:
        a, b, c = coef[0], -1., coef[1]
    elif len(coef) == 3:
        a, b, c = coef
    ax = gca()

    limits = ax.axis()
    print limits
    points = __intersect(limits, (a,b,c))
    print points
    if len(points) == 2:
        pts = array(points)
        ax.plot(pts[:,0], pts[:,1], *args, **kwargs)
        ax.axis(limits)

1 Comment

I'm sorry, but I don't understand. Where do you use any of the outcome of the SVM in your answer to plot the hyperplane?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.