【问题标题】:How to implement Perceptron in Python?如何在 Python 中实现感知器?
【发布时间】:2018-04-23 03:43:48
【问题描述】:

我正在努力学习 Daume 的书

http://ciml.info/dl/v0_99/ciml-v0_99-ch04.pdf(第 43 页)。

使用 numpy 和不使用 numpy 在 python 中拟合 vanilla perceptron 模型 使用 sciki-learn 库。

算法在书中给出

我们如何在实践中实现这个模型?

到目前为止,我已经学会了如何读取数据和标签:

def read_data(infile):
    data = np.loadtxt(infile)
    X = data[:,:-1]
    Y = data[:,-1]

    return X, Y

我们将不胜感激!

【问题讨论】:

    标签: python numpy machine-learning perceptron


    【解决方案1】:

    我想出的一种方法是:

    (总是欢迎更好的想法!)

    #!python
    # -*- coding: utf-8 -*-#
    """
    Perceptron Algorithm.
    
    @author: Bhishan Poudel
    
    @date:  Oct 31, 2017
    
    """
    # Imports
    import numpy as np
    import matplotlib.pyplot as plt
    from numpy.linalg import norm
    import os, shutil
    np.random.seed(100)
    
    def read_data(infile):
        data = np.loadtxt(infile)
        X = data[:,:-1]
        Y = data[:,-1]
    
        return X, Y
    
    def plot_boundary(X,Y,w,epoch):
        try:
            plt.style.use('seaborn-darkgrid')
            # plt.style.use('ggplot')
            #plt.style.available
        except:
            pass
    
        # Get data for two classes
        idxN = np.where(np.array(Y)==-1)
        idxP = np.where(np.array(Y)==1)
        XN = X[idxN]
        XP = X[idxP]
    
        # plot two classes
        plt.scatter(XN[:,0],XN[:,1],c='b', marker='_', label="Negative class")
        plt.scatter(XP[:,0],XP[:,1],c='r', marker='+', label="Positive class")
        # plt.plot(XN[:,0],XN[:,1],'b_', markersize=8, label="Negative class")
        # plt.plot(XP[:,0],XP[:,1],'r+', markersize=8, label="Positive class")
        plt.title("Perceptron Algorithm iteration: {}".format(epoch))
    
        # plot decision boundary orthogonal to w
        # w is w2,w1, w0  last term is bias.
        if len(w) == 3:
            a  = -w[0] / w[1]
            b  = -w[0] / w[2]
            xx = [ 0, a]
            yy = [b, 0]
            plt.plot(xx,yy,'--g',label='Decision Boundary')
    
        if len(w) == 2:
            x2=[ w[0],  w[1],  -w[1],  w[0]]
            x3=[ w[0],  w[1],   w[1], -w[0]]
    
            x2x3 =np.array([x2,x3])
            XX,YY,U,V = list(zip(*x2x3))
            ax = plt.gca()
            ax.quiver(XX,YY,U,V,scale=1, color='g')
    
        # Add labels
        plt.xlabel('X')
        plt.ylabel('Y')
    
        # limits
        x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
        y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
        plt.xlim(x_min,x_max)
        plt.ylim(y_min,y_max)
    
        # lines from origin
        plt.axhline(y=0, color='k', linestyle='--',alpha=0.2)
        plt.axvline(x=0, color='k', linestyle='--',alpha=0.2)
        plt.grid(True)
        plt.legend(loc=1)
        plt.show()
    
        # Always clost the plot
        plt.close()
    
    
    def predict(X,w):
        return np.sign(np.dot(X, w))
    
    def plot_contour(X,Y,w,mesh_stepsize):
        try:
            plt.style.use('seaborn-darkgrid')
            # plt.style.use('ggplot')
            #plt.style.available
        except:
            pass    
        # Get data for two classes
        idxN = np.where(np.array(Y)==-1)
        idxP = np.where(np.array(Y)==1)
        XN = X[idxN]
        XP = X[idxP]
    
        # plot two classes with + and - sign
        fig, ax = plt.subplots()
        ax.set_title('Perceptron Algorithm')
        plt.xlabel("X")
        plt.ylabel("Y")
        plt.plot(XN[:,0],XN[:,1],'b_', markersize=8, label="Negative class")
        plt.plot(XP[:,0],XP[:,1],'y+', markersize=8, label="Positive class")
        plt.legend()
    
        # create a mesh for contour plot
        # We first make a meshgrid (rectangle full of pts) from xmin to xmax and ymin to ymax.
        # We then predict the label for each grid point and color it.
        x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
        y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    
        # Get 2D array for grid axes xx and yy  (shape = 700, 1000)
        # xx has 700 rows.
        # xx[0] has 1000 values.
        xx, yy = np.meshgrid(np.arange(x_min, x_max, mesh_stepsize),
                             np.arange(y_min, y_max, mesh_stepsize))
    
        # Get 1d array for x and y axes
        xxr = xx.ravel()  # shape (700000,)
        yyr = yy.ravel()  # shape (700000,)
    
        # ones vector
        # ones = np.ones(xxr.shape[0]) # shape (700000,)
        ones = np.ones(len(xxr)) # shape (700000,)
    
        # Predict the score
        Xvals  = np.c_[ones, xxr, yyr]
        scores = predict(Xvals, w)
    
        # Plot contour plot
        scores = scores.reshape(xx.shape)
        ax.contourf(xx, yy, scores, cmap=plt.cm.Paired)
        # print("xx.shape = {}".format(xx.shape))               # (700, 1000)
        # print("scores.shape = {}".format(scores.shape))       # (700, 1000)
        # print("scores[0].shape = {}".format(scores[0].shape)) # (1000,)
    
        # show the plot
        plt.savefig("Perceptron.png")
        plt.show()
        plt.close()
    
    def perceptron_sgd(X, Y,epochs):
        """
        X: data matrix without bias.
        Y: target
        """
        # add bias to X's first column
        ones = np.ones(X.shape[0]).reshape(X.shape[0],1)
        X1 = np.append(ones, X, axis=1)
    
    
        w = np.zeros(X1.shape[1])
        final_iter = epochs
    
        for epoch in range(epochs):
            print("\n")
            print("epoch: {} {}".format(epoch, '-'*30))
    
            misclassified = 0
            for i, x in enumerate(X1):
                y = Y[i]
                h = np.dot(x, w)*y
    
                if h <= 0:
                    w = w + x*y
                    misclassified += 1
                    print('misclassified? yes  w: {} '.format(w,i))
    
                else:
                    print('misclassified? no  w: {}'.format(w))
                    pass
    
            if misclassified == 0:
                final_iter = epoch
                break
    
        return w, final_iter
    
    def gen_lin_separable_data(data, data_tr, data_ts,data_size):
        mean1 = np.array([0, 2])
        mean2 = np.array([2, 0])
        cov = np.array([[0.8, 0.6], [0.6, 0.8]])
        X1 = np.random.multivariate_normal(mean1, cov, size=int(data_size/2))
        y1 = np.ones(len(X1))
        X2 = np.random.multivariate_normal(mean2, cov, size=int(data_size/2))
        y2 = np.ones(len(X2)) * -1
    
    
        with open(data,'w') as fo, \
             open(data_tr,'w') as fo1, \
             open(data_ts,'w') as fo2:
            for i in range( len(X1)):
                line = '{:5.2f} {:5.2f} {:5.0f} \n'.format(X1[i][0], X1[i][1], y1[i])
                line2 = '{:5.2f} {:5.2f} {:5.0f} \n'.format(X2[i][0], X2[i][1], y2[i])
                fo.write(line)
                fo.write(line2)
    
            for i in range( len(X1) - 20):
                line = '{:5.2f} {:5.2f} {:5.0f} \n'.format(X1[i][0], X1[i][1], y1[i])
                line2 = '{:5.2f} {:5.2f} {:5.0f} \n'.format(X2[i][0], X2[i][1], y2[i])
                fo1.write(line)
                fo1.write(line2)
    
            for i in range((len(X1) - 20), len(X1) ):
                line = '{:5.2f} {:5.2f} {:5.0f} \n'.format(X1[i][0], X1[i][1], y1[i])
                line2 = '{:5.2f} {:5.2f} {:5.0f} \n'.format(X2[i][0], X2[i][1], y2[i])
                fo2.write(line)
                fo2.write(line2)
    
    def main():
        """Run main function."""
    
        # generate linearly separable data
        data = 'data.txt'
        data_tr = 'data_train.txt'
        data_ts = 'data_test.txt'
        data_size = 200
        gen_lin_separable_data(data, data_tr, data_ts,data_size)
    
        # read data
        epochs = 20
        X_train, Y_train = read_data(data_tr)
        X_test, Y_test = read_data(data_ts)
    
        # fit perceptron 
        w, final_iter = perceptron_sgd(X_train,Y_train,epochs)
        print('w = ', w)
    
        plot_boundary(X_test,Y_test,w,final_iter)
    
        # contour plot
        mesh_stepsize = 0.01
        plot_contour(X_test,Y_test,w,mesh_stepsize)
    
    if __name__ == "__main__":
        main()
    

    决策边界如下所示:

    【讨论】:

      【解决方案2】:

      在我最近的 repo 中有一个感知器的实现:NP_ML。示例结果是:

      【讨论】:

      猜你喜欢
      • 2018-04-23
      • 2015-04-25
      • 2017-12-28
      • 2011-06-07
      • 2019-01-20
      • 2018-07-28
      • 2015-12-05
      • 1970-01-01
      • 2017-04-09
      相关资源
      最近更新 更多