機器學習-感知機Perceptron

Section I: Brief Introduction on Perceptron

The whole idea behind the MCP neuron and Rosenblatt’s thresholded percepton model is to use a reductionist approach to mimic how a single neuron in the brain works: it either fires or it doesn’t. Thus, this perceptron rule is fairly simple and can be summarized by the following steps:

  • Step 1: 初始化權重爲0或者較小值
  • Step 2: 對於每一個訓練樣本,執行如下操作:
    • Step 2.1: 依據權重和輸入向量,以點積方式計算輸出
    • Step 2.2: 更新權重參數
Section II: Code Snipet

Part I: Perceptron Code

import numpy as np

class Perceptron(object):
    """
    Perceptron classifier

    Parameters
    ----------
    eta:
     - learning rate between 0 and 1
    n_iter:
     - passes over the training dataset
    random_state:
     - random number generator seed for random weight initialization

    Attributes:
    -----------
    w_:
     - weights after fitting
    errors_:
     - number of misclassifications or updates in each epoch
    """
    def __init__(self,eta=0.01,n_iter=50,random_state=1):
        self.eta=eta
        self.n_iter=n_iter
        self.random_state=random_state

    def fit(self,X,y):
        """
        Fitting training data
        :param X: shape-[n_samples,n_features]
        :param y: target values
        :return: self
        """
        rgen=np.random.RandomState(self.random_state)
        self.w_=rgen.normal(loc=0.0,scale=0.01,size=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)

Part II: Two-dimensional Scatterplot of Two Features

#Section I: Load data
import pandas as pd
from sklearn import datasets

iris=datasets.load_iris()
df=pd.DataFrame(iris.data[:,[0,2]],columns=iris.feature_names[:2])
df.tail()

#Section II: Visualize two features of Iris dataset
import matplotlib.pyplot as plt
import numpy as np

#Step 1: Select setosa and versicolor
y=iris.target[:100]
y=np.where(y==0,-1,1)

#Step 2: Extract sepal length and petal length
X=df.iloc[0:100,:].values

#Step 3: Plot data
plt.rcParams['figure.dpi']=200
plt.rcParams['savefig.dpi']=200
font = {'family': 'Times New Roman',
        'weight': 'light'}
plt.rc("font", **font)

plt.scatter(X[:50,0],X[:50,1],color='red',marker='o',label='setosa')
plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='versicolor')
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.savefig('./fig1.png')
plt.show()

在這裏插入圖片描述
由上圖可以得知,依據sepal長度和petal長度兩位特徵空間,顯然是線性可分。

Part III: Train Perceptron on the Iris Dataset

from Perceptron import perceptron

ppn=perceptron.Perceptron(eta=0.1,n_iter=40)
ppn.fit(X,y)
plt.plot(range(1,len(ppn.errors_)+1),ppn.errors_,marker='o')
plt.xlabel('Epoches')
plt.ylabel('Number of updates')
plt.savefig('./fig2.png')
plt.show()

在這裏插入圖片描述

Part IV: Depict Plot Decision

from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import numpy as np

def plot_decision_regions(X, y, classifier, resolution=0.02):
    """
    Plots decision regions of a classifier.

    Parameters
    ----------
    X : array-like, shape = [n_samples, n_features]
      Feature Matrix.

    y : array-like, shape = [n_samples]
      True class labels.

    clf : Classifier object. Must have a .predict method.

    res : float (default: 0.02)
      Grid width. Lower values increase the resolution but
        slow down the plotting.

    Returns
    ---------
    None

    """
    markers=('s','x','o','^','v')
    colors=('red','blue','lightgreen','gray','cyan')
    cmap=ListedColormap(colors[:len(np.unique(y))])
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, resolution),
                         np.arange(y_min, y_max, resolution))

    Z = classifier.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    plt.contourf(xx, yy, Z, alpha=0.4,cmap=cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)

    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())

    for idx,cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y==cl,0],
                    y=X[y==cl,1],
                    alpha=0.8,
                    c=colors[idx],
                    marker=markers[idx],
                    label=cl,
                    edgecolors='black')

調用方式:

#Section IV: Visualize decision boundaries
from Perceptron.visualize import  plot_decision_regions

plot_decision_regions(X,y,classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.savefig('./fig3.png')
plt.show()

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章