感知机模型

模型概念#

输入空间和输出空间#

  • XRn
  • Y={+1,1}
  • xX
  • yY

假设空间#

f(x)=sign(wx+b)

wb是感知机的模型参数,wRn叫做权重向量bR叫做偏置wx表示wx的内积,sign是符号函数,即

sign(x)={+1x01x<0

学习策略#

x0到直线y=wx+b的距离

distance=1||w|||wx0+b|

对于误分类点(xi,yi),如果wxi+b<0,那么yi=+1;反之,如果wxi+b>0,那么yi=1。所以,将距离公式去掉绝对值,误分类点到超平面的距离可以表示为

1||w||yi(wxi+b)

损失函数的定义:误分类点到超平面的总距离

L(w,b)=xiM1||w||yi(wxi+b)

其中M为误分类点的集合

对于感知机算法使用梯度下降法求解

Lw=xiMyixiLb=xiMyi

在训练过程中,使用随机梯度下降法,随机选取一个误分类点,对wb更新

w=w+ηyixib=b+ηyy

问题:为什么参数更新的时候不需要考虑1||w||?

分离超平面通过wb确定,1||w||w的方向没有影响,可以固定w的大小为1。

从上述学习过程中可以看出来,假如wb的初始值都设为0η的初始值设为1,那么w在误分类点(xi,yi)的驱动下的增量为yixib的增量为yi。设误分类点(xi,yi)wb的修正次数为ai,那么最终w=i=1Naiyixib=i=1Naiyi

此时的模型可以表示为

f(x)=sign(j=1Najyjxjx+b)

算法#

感知机学习算法的原始形式#

class Perceptron:
    def __init__(self, alpha=0.1):
        self.alpha = alpha
        self.w = None
        self.b = None

    def fit(self, X, y):
        self.w = np.ones_like(X[0])
        self.b = 0.0
        flag = 1
        while flag:
            flag = 0
            for xi, yi in zip(X, y):
                if yi * (np.dot(self.w, xi) + self.b) <= 0:
                    self.w += self.alpha * yi * xi
                    self.b += self.alpha * yi
                    flag = 1

可视化结果

def plot(X, y, model):
    w = model.w
    b = model.b
    print(w, b)
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap='rainbow')
    plt.plot(range(5), [-w[0] / w[1] * x - model.b / w[0] for x in range(5)], c="b")
    plt.xlabel("x [0]")
    plt.ylabel("x [1]")
    plt.title("Perceptron Algorithm")
    plt.show()


def main():
    model = Perceptron(alpha=1)
    X = np.array([[3., 3.], [4., 3.], [1., 1.]])
    y = np.array([1., 1., -1.])
    model.fit(X, y)
    plot(X, y, model)

感知机学习算法的对偶形式#

class Perceptron:
    def __init__(self, alpha=0.1):
        self.alpha = alpha
        self.a = None
        self.b = None

    def fit(self, X, y):
        self.a = np.zeros(X.shape[0])
        self.b = 0.0
        flag = 1
        while flag:
            flag = 0
            for i, (xi, yi) in enumerate(zip(X, y)):
                if yi * (sum([self.a[j] * y[j] * np.dot(x, xi) for j, x in enumerate(X)]) + self.b) <= 0:
                    self.a[i] += self.alpha
                    self.b += self.alpha * yi
                    flag = 1

可视化结果

def plot(X, y, model):
    w = np.sum(np.array([model.a[i] * y[i] * x for i, x in enumerate(X)]), axis=0)
    b = np.sum(np.array([model.a[i] * y[i] for i, x in enumerate(X)]), axis=0)
    print(w, b)
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap='rainbow')
    plt.plot(range(5), [-w[0] / w[1] * x - model.b / w[0] for x in range(5)], c="b")
    plt.xlabel("x [0]")
    plt.ylabel("x [1]")
    plt.title("Perceptron Algorithm")
    plt.show()


def main():
    model = Perceptron(alpha=1)
    X = np.array([[3., 3.], [4., 3.], [1., 1.]])
    y = np.array([1., 1., -1.])
    model.fit(X, y)
    plot(X, y, model)

算法的收敛性#

详细证明过程参照李航老师《统计学习方法》

算法的收敛性证明表明,在数据集线性可分的情况下,搜索次数k是有上界的,经过有限次搜索可以找到将训练数据完全正确分开的超平面。

posted @   crazypigf  阅读(27)  评论(0编辑  收藏  举报
 
点击右上角即可分享
微信分享提示
主题色彩