<jupyter_start><jupyter_text>Perceptron Learning AlgorithmPython InitializationStart by setting up the environment<jupyter_code>import numpy as np
import matplotlib 
import matplotlib.pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>PerceptronThe perceptron is a linear classifier that operates based on the pseudo-code shown below:![pseudocode](../references/pseudocode.png) Part One: Perceptron UpdateImplement the function below to update the perceptron given an input vector, label, and weight vector. Do not check if an update is necessary. This function can assume that it is only called when an update should be performed.<jupyter_code>def perceptron_update(x, y, w):
    return w + y * x<jupyter_output><empty_output><jupyter_text>Part Two: Implement PerceptronImplement function perceptron. This contains a loop that calls perceptron_update until it converges or the maximum iteration count has been reached.<jupyter_code>def perceptron(xs, ys, max_iter=1_000):
    n, d = xs.shape
    w = np.zeros(d)
    b = 0.0
    
    iterations = 0
    while True:
        # set number of misclassifications to zero
        m = 0
        
        # update iteration counter
        iterations += 1
        
        # shuffle the data
        ix = np.random.permutation(n)
        xs = xs[ix,:]
        ys = ys[ix]
        
        # iterate over data
        for x, y in zip(xs, ys):
            if y * np.dot(w.T, x) <= 0:
                # update weights
                w = perceptron_update(x, y, w)
                
                # increase misclassification count
                m += 1
        
        # end condition
        if m == 0 or iterations >= max_iter:
            break
    
    return (w,b)<jupyter_output><empty_output><jupyter_text>Visualize Your Perceptron The following script tests the code and visualizes the perceptron on linearly separable data in 2 dimensions.<jupyter_code>from numpy.matlib import repmat

def visboundary(w, b, xs, ys):
    res = 300
    symbols = ['ko', 'kx']
    colors = [[0.5, 0.5, 1], [1, 0.5, 0.5]]
    classes = [-1, 1]
    
    xrange = np.linspace(-5, 5, res)
    yrange = np.linspace(-5, 5, res)
    pixelX = repmat(xrange, res, 1)
    pixelY = repmat(yrange, res, 1).T
    
    testPoints = np.array([pixelX.flatten(), pixelY.flatten()]).T
    testLabels = np.dot(testPoints, w) + b
    
    Z = testLabels.reshape(res, res)
    plt.contourf(pixelX, pixelY, np.sign(Z), colors=colors)
    plt.scatter(xs[ys == classes[0], 0], xs[ys == classes[0], 1], marker='o', color='k')
    plt.scatter(xs[ys == classes[1], 0], xs[ys == classes[1], 1], marker='x', color='k')
    
    q = -b / (w ** 2).sum() * w
    plt.quiver(q[0], q[1], w[0], w[1], linewidth=1.0, color=[0, 1, 0])
    plt.axis('tight')
    plt.xlim([-5, 5])
    plt.ylim([-5, 5])
    plt.show()
# number of input vectors
N = 100

# generate random (linearly separable) data
xs = np.random.rand(N, 2) * 10 - 5

# defining random hyperplane
w0 = np.random.rand(2)
b0 = np.random.rand() * 2 - 1

# assign labels +1, -1 labels depending on what side of the plane they lie on
ys = np.sign(xs.dot(w0) + b0)

# call perceptron to find w from data
w, b = perceptron(xs.copy(), ys.copy(), max_iter=1_000)

# we can make a pretty visualization
visboundary(w, b, xs, ys)<jupyter_output><empty_output><jupyter_text>Part Three: Make Predictionsclassify_linear applies the weight vector and bias to the input vector. (The bias is an optional parameter. If it is not passed in, assume it is zero.) The predictions return are either 1 or -1.<jupyter_code>def classify_linear(xs, w, b=0):
    w = w.flatten() 
    predictions = np.zeros(xs.shape[0])
    predictions = np.sign(xs @ w + b)
    
    return predictions
# see how well function performs
import matplotlib as mpl
mpl.style.use('ggplot')

c = classify_linear(xs, w, b)
plt.scatter(xs[ys == c,0], xs[ys == c,1], c=c[ys==c], s=60)
plt.scatter(xs[ys != c,0], xs[ys != c,1], c='red', marker='x', s=1_000)
score = np.mean(c == ys)
print('Accuracy Score: {0:.2%}'.format(score))<jupyter_output>Accuracy Score: 96.00%
{'fraction_non_alphanumeric': 0.12576312576312576, 'fraction_numerical': 0.023443223443223443, 'mean_word_length': 3.1165829145728643, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '57368', 'license': 'MIT', 'n_tokens_mistral': 1501, 'n_tokens_neox': 1401, 'n_words': 434, 'path': 'notebooks/perceptron.ipynb', 'repo_name': 'Joshua-Robison/eCornell', 'size': '4095'}