perceptron

感知机是机器学习入门的第一个算法,也是最简单的算法。我们可以从理论上证明,对于一个线性可分的分类问题,感知机总能在有限次迭代后从无限的假设空间中找到一个解。

代码所做的工作主要是假定分界线f已知,由此随机生成数据,然后用感知机模型找到一个边界并显示在图上。

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

#判断是否所有样本已被正确分类
def judge(X, y, w):
    n = X.shape[0]
    # 判断是否同号
    num = np.sum(X.dot(w) * y > 0)
    return num == n

#生成N个d维点(不包括偏置项1),x1+...+xd>0的点标记为+1,x1+...+xd<=0的点标记为-1
def data(N, d, rnd):
    X = []
    w = np.ones(d)
    while (len(X) < N):
        #rnd为随机数生成器,rnd = np.random.RandomState(seed),seed为随机种子
        x = rnd.uniform(-1, 1, size=(d))
        if x.dot(w) != 0:
            X.append(x)

    X = np.array(X)
    y = 2 * (X.dot(w) > 0) - 1
    # 添加第一个分量为1
    X = np.c_[np.ones((N, 1)), X]

    return X, y

def f(N, d, rnd):
    #生成数据
    X, y = data(N, d, rnd)
    #迭代次数
    s = 0
    #初始化w
    w = np.zeros(d + 1)
    #样本数
    n = X.shape[0]

    while(judge(X, y, w) == 0):
        for i in range(n):
            if X[i, :].dot(w) * y[i] <= 0:
                w = w + y[i] * X[i, :]
                s = s + 1

    return X, y, w, s

#画出感知机找到的边界
def border_plot(X, y, w, s):
    x1 = np.arange(-1, 1, 0.1)
    x2 = np.arange(-1, 1, 0.1)
    x1, x2 = np.meshgrid(x1, x2)

    plt.scatter(X[y == 1][:, 1], X[y == 1][:, 2], c='r', s=1)
    plt.scatter(X[y == -1][:, 1], X[y == -1][:, 2], c='b', s=1)
    f = w[0] + w[1] * x1 + w[2] * x2
    plt.contour(x1, x2, f, 0,)
    plt.title(u"经过" + str(s) + u"次迭代收敛")
    plt.show()

#初始化参数并运行
seed = 20
rnd = np.random.RandomState(seed)
N = 30
d = 2
X, y, w, s = f(N, d, rnd)
border_plot(X, y, w, s)

运行结果示例:

perceptron_第1张图片
perceptron_第2张图片

你可能感兴趣的:(perceptron)