如何在Python中实现感知器?

如何在Python中实现感知器?,python,numpy,machine-learning,perceptron,Python,Numpy,Machine Learning,Perceptron,我正努力跟着我的书走 (第43页) 在python中使用numpy和不使用numpy来拟合香草感知器模型 使用sciki学习库 书中给出了算法 我们如何在实践中实施这一模式 到目前为止,我已经学会了如何读取数据和标签: def read_data(infile): data = np.loadtxt(infile) X = data[:,:-1] Y = data[:,-1] return X, Y 谢谢你的帮助 我发现的一个方法是: (欢迎提出更好的想法!

我正努力跟着我的书走

(第43页)

在python中使用numpy和不使用numpy来拟合香草感知器模型 使用sciki学习库

书中给出了算法

我们如何在实践中实施这一模式

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

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

    return X, Y

谢谢你的帮助

我发现的一个方法是:

(欢迎提出更好的想法!!)

#!python
#-*-编码:utf-8-*-#
"""
感知器算法。
@作者:比珊·普德尔
@日期:2017年10月31日
"""
#进口
将numpy作为np导入
将matplotlib.pyplot作为plt导入
来自numpy.linalg进口规范
导入操作系统,shutil
np.随机种子(100)
def读取数据(填充):
数据=np.loadtxt(infle)
X=数据[:,:-1]
Y=数据[:,-1]
返回X,Y
def绘图_边界(X、Y、w、历元):
尝试:
plt.style.use('seaborn-darkgrid'))
#plt.style.use('ggplot'))
#plt.style.available
除:
通过
#获取两个类的数据
idxN=np.where(np.array(Y)=-1)
idxP=np.where(np.array(Y)==1)
XN=X[idxN]
XP=X[idxP]
#绘制两个类
plt.scatter(XN[:,0],XN[:,1],c='b',marker='',label=“负类”)
plt.scatter(XP[:,0],XP[:,1],c='r',marker='+',label=“正类”)
#plt.plot(XN[:,0],XN[:,1],'b_u2;',markersize=8,label=“负类”)
#plt.plot(XP[:,0],XP[:,1],'r+',markersize=8,label=“正类”)
标题(“感知器算法迭代:{}”。格式(历元))
#绘制与w正交的决策边界
#w是w2,w1,w0最后一项是偏差。
如果len(w)==3:
a=-w[0]/w[1]
b=-w[0]/w[2]
xx=[0,a]
yy=[b,0]
plt.图(xx,yy,'--g',label='Decision Boundary')
如果len(w)==2:
x2=[w[0],w[1],-w[1],w[0]]
x3=[w[0],w[1],w[1],-w[0]]
x2x3=np.数组([x2,x3])
二十、 YY,U,V=列表(zip(*x2x3))
ax=plt.gca()
最大震颤(XX,YY,U,V,刻度=1,颜色=g')
#添加标签
plt.xlabel('X')
plt.ylabel('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
plt.xlim(最小x_,最大x_)
plt.ylim(y_最小值,y_最大值)
#来自原点的线条
plt.axhline(y=0,color=k,linestyle='--',alpha=0.2)
plt.axvline(x=0,color='k',linestyle='--',alpha=0.2)
plt.grid(真)
plt.图例(loc=1)
plt.show()
#总是把情节搞定
plt.close()
def预测(X,w):
返回np.符号(np.点(X,w))
def plot_轮廓(X、Y、w、网格步长):
尝试:
plt.style.use('seaborn-darkgrid'))
#plt.style.use('ggplot'))
#plt.style.available
除:
通过
#获取两个类的数据
idxN=np.where(np.array(Y)=-1)
idxP=np.where(np.array(Y)==1)
XN=X[idxN]
XP=X[idxP]
#用+和-符号绘制两个类
图,ax=plt.子批次()
ax.set_title(‘感知器算法’)
plt.xlabel(“X”)
plt.ylabel(“Y”)
plt.plot(XN[:,0],XN[:,1],'b_u2;',markersize=8,label=“负类”)
plt.plot(XP[:,0],XP[:,1],'y+',markersize=8,label=“正类”)
plt.legend()
#为等高线打印创建网格
#我们首先制作一个从xmin到xmax、从ymin到ymax的网格(充满pts的矩形)。
#然后,我们预测每个网格点的标签并为其着色。
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的二维阵列(形状=7001000)
#xx有700行。
#xx[0]有1000个值。
xx,yy=np.meshgrid(np.arange(x_最小值,x_最大值,网格步长),
np.arange(y_最小值,y_最大值,网格尺寸)
#获取x轴和y轴的1d阵列
xxr=xx.ravel()#形状(700000,)
yyr=yy.ravel()#形状(700000,)
#一个向量
#一个=np.一个(xxr.形状[0])#形状(700000,)
一个=np.一个(透镜(xxr))#形状(700000,)
#预测分数
Xvals=np.c_u2;[一,xxr,yyr]
分数=预测(xVAL,w)
#绘制等高线图
分数=分数。重塑(xx.形状)
最大轮廓f(xx,yy,分数,cmap=plt.cm.成对)
#打印(“xx.shape={}”。格式(xx.shape))#(7001000)
#打印(“scores.shape={}”。格式(scores.shape))#(7001000)
#打印(“分数[0]。形状={}”。格式(分数[0]。形状))#(1000,)
#展示情节
plt.savefig(“Perceptron.png”)
plt.show()
plt.close()
def感知机(X、Y、历代):
"""
X:无偏差的数据矩阵。
Y:目标
"""
#将偏差添加到X的第一列
一=np.一(X.形状[0])。重塑(X.形状[0],1)
X1=np.追加(1,X,轴=1)
w=np.零(X1.形[1])
最终试验=时代
对于范围内的历元(历元):
打印(“\n”)
打印(“历元:{}{}”。格式(历元,'-'*30))
误分类=0
对于枚举(X1)中的i,x:
y=y[i]
h=np.点(x,w)*y

如果h在我最近的报告中有感知器的实现:。示例结果是:

看起来棒极了!除了一个链接之外,您还可以发布任何相关的代码吗?好的,下面是实现代码:上面的示例如下:
#!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()