In [1]:
class Perceptron_byHand:
    def __init__(self, N, eta=0.2):
        self.W = np.zeros(N)
        self.eta = eta
        
    def step(self, value):
        if value >= 0:
            return 1
        else:
            return -1
        
    def forward_prop(self, x_input):
        return np.dot(self.W, x_input)
        
    def getScore(self, X, Y):
        cnt = 0
        for key, val in enumerate(X):
            if self.step( self.forward_prop(val) ) != Y[key]:
                cnt +=1 
        return 1 - cnt/float(len(X))
            
    
    def fit(self, X, Y, iterations=0):
        if not iterations:
            iterations = len(Y)
        for i in range(iterations):
            ind = np.random.randint(0, len(Y)) #Pick randomly a training example index
            prediction = self.step( self.forward_prop(X[ind]) ) 
            if prediction != Y[ind]:  # We need to update the weights, because we made an error
                error = Y[ind] - prediction
                self.W = self.W + self.eta * Y[ind] * X[ind]
        print (self.getScore(X,Y))
                
    def predict(self, X):
        return self.step( self.forward_prop(X[ind]) )
        
    def visualize(self, X, Y):
        plt.plot(X[:, 1][Y==1], X[:, 2][Y==1], 'ro')
        plt.plot(X[:, 1][Y==-1], X[:, 2][Y==-1], 'bo')
        plt.xlim([-1, 1])
        plt.ylim([-1, 1])
        x = np.linspace(-1,1)
        a, b = -self.W[1]/self.W[2], -self.W[0]/self.W[2]
        plt.plot(x, a*x+b, 'k-')

In [11]:
import random, matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

# Generates some data
def generate_points(N, V):
    X = []
    for i in range(N):
        x1,x2 = [random.uniform(-1, 1) for i in range(2)]
        x = np.array([1,x1,x2])
        s = int(np.sign(V.T.dot(x)))
        X.append((x, s))
    return X
xA,yA,xB,yB = [random.uniform(-1, 1) for i in range(4)]
V = np.array([xB*yA-xA*yB, yB-yA, xA-xB])
X = generate_points(100, V)
Z, Y  = np.array([i[0] for i in X]), np.array([i[1] for i in X])
# Y[Y==-1] = 0

In [12]:
clf = Perceptron_byHand(3, 0.2)
for i in range(0, 10):
    print ("Epoch: %d"%i,)
    clf.fit(Z,Y)
    fig = plt.figure(figsize=(5,5))
clf.visualize(Z, Y)


Epoch: 0
0.98
Epoch: 1
0.98
Epoch: 2
0.99
Epoch: 3
0.99
Epoch: 4
0.98
Epoch: 5
1.0
Epoch: 6
1.0
Epoch: 7
1.0
Epoch: 8
1.0
Epoch: 9
1.0
<matplotlib.figure.Figure at 0x10d2ee1d0>
<matplotlib.figure.Figure at 0x10d2ee198>
<matplotlib.figure.Figure at 0x10d2ee208>
<matplotlib.figure.Figure at 0x10d2f4358>
<matplotlib.figure.Figure at 0x10d2f4390>
<matplotlib.figure.Figure at 0x10d2f4cc0>
<matplotlib.figure.Figure at 0x10d3030b8>
<matplotlib.figure.Figure at 0x10d303a90>
<matplotlib.figure.Figure at 0x10d3094a8>

In [ ]: