Build Perceptron to Classify Iris Data with Python

It would be interesting to write some basic neuron function for classification, helping us refresh some essential points in neural network.
Used sublime text3 and Ipython3 as IDE, and the code mostly came from: https://www.goodreads.com/book/show/25545994-python-machine-learning?from_search=true

import pandas as pd 
df=pd.read_csv('iris.data', header=None)
def rstr(df):
	return df.shape, df.apply(lambda x:[x.unique()])
print(df.tail())

print(rstr(df))

import matplotlib.pyplot as plt 
import numpy as np 

### select training data and identify label
y=df.iloc[0:100,4].values
y=np.where(y=='Iris-setosa',-1,1) 
x=df.iloc[0:100,[0,2]].values

###plot 'setosa' and 'versicolor'
plt.scatter(x[:50,0],x[:50,1],color='r',marker='o',label='setosa')
plt.scatter(x[50:100,0],x[50:100,1],color='b',marker='x',label='versicolor')
plt.xlabel('petal length')
plt.ylabel('sepal length')
plt.legend(loc='best')
plt.show()

figure_1

###now we define the necessary functions, especiall the fit()
class Perceptron(object):
    """Perceptron classifier.
    Parameters
    ------------
    eta : float
        Learning rate (between 0.0 and 1.0)
    n_iter : int
        Passes over the training dataset.
    Attributes
    -----------
    w_ : 1d-array
        Weights after fitting.
    errors_ : list
        Number of misclassifications in every epoch.
    """
    def __init__(self, eta=0.01, n_iter=10):
        self.eta = eta
        self.n_iter = n_iter

    def fit(self, x, y):
        """Fit training data.
        Parameters
        ----------
        X : {array-like}, shape = [n_samples, n_features]
            Training vectors, where n_samples
            is the number of samples and
            n_features is the number of features.
        y : array-like, shape = [n_samples]
            Target values.
		Returns
           -------
        self : object
           """
        self.w_ = np.zeros(1 + x.shape[1])
        self.errors_ = []
        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(x, y):
            	update = self.eta * (target - self.predict(xi))
            	self.w_[1:] += update * xi
            	self.w_[0] += update
            	errors += int(update != 0.0)
            self.errors_.append(errors)
        return self
    def net_input(self, x):
        """Calculate net input"""
        return np.dot(x, self.w_[1:]) + self.w_[0]
    def predict(self, x):
        """Return class label after unit step"""
        return np.where(self.net_input(x) >= 0.0, 1, -1)    
       
### now we use the defined function to train the model
ppn=Perceptron(eta=0.1,n_iter=10)
ppn.fit(x,y)
plt.plot(range(1,len(ppn.errors_)+1),ppn.errors_,marker='o')
plt.xlabel('Epochs')
plt.ylabel('Number of misclassifications')
plt.show()

Screen Shot 2017-05-16 at 8.35.48 PM

###and we can make it more visualized with another defined function 
from matplotlib.colors import ListedColormap 
def plot_decision_regions(X, y, classifier, resolution=0.02):
    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])
    # plot the decision surface
    x1_min, x1_max = x[:, 0].min() - 1, x[:, 0].max() + 1
    x2_min, x2_max = x[:, 1].min() - 1, x[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                         np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())
    # plot class samples
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=x[y == cl, 0], y=x[y == cl, 1],
                    alpha=0.8, c=cmap(idx),
                    marker=markers[idx], label=cl)

###finally we plot the predicted results
plot_decision_regions(x, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

Screen Shot 2017-05-16 at 9.23.05 PM

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s