李航统计学习方法之感知机学习(含感知机原始形式和对偶形式Python代码实现)

感知机

感知机基本介绍

感知机是一个线性二分模型,输出取值为{-1, 1}。是判别模型。
  感知机是为了求解一个超平面,该超平面能够将特征空间里的实例分解为正例和负例。设超平面方程为y=w*x+b,因此,引入基于误分类点的损失函数。如果损失函数为误分类点个数,则该损失函数不是wb的连续可导函数,不利于优化。我们考虑另一个选择:误分类点距离该超平面的距离。
  假设空间任意 一点 ( x 0 , y 0 ) (x_0,y_0) (x0,y0) 到平面 y = w ∗ x + b y = w*x + b y=wx+b 的距离可以写成: 1 ∣ ∣ w ∣ ∣ ∗ ∣ w ∗ x 0 + b ∣ \frac {1} {||w||} * |w*x_0+b| w1wx0+b,其中, ∣ ∣ w ∣ ∣ ||w|| w 表示 w w w的二范数。那么误分类点到该平面距离为 − y i ∗ ( w ∗ x i + b ) &gt; 0 -y_i*(w*x_i+b) &gt; 0 yi(wxi+b)>0,这是因为对于误分类点,对于 y i = 1 y_i=1 yi=1 w ∗ x i + b &lt; 0 w*x_i+b&lt;0 wxi+b<0 , y i = − 1 y_i=-1 yi=1 w ∗ x i + b &gt; 0 w*x_i+b&gt;0 wxi+b>0
  因此,对于误分类点 ( x i , y i ) (x_i, y_i) (xi,yi),该点到平面的距离为 1 ∣ ∣ w ∣ ∣ ∗ [ − y i ∗ ( w ∗ x i ) ] \frac {1} {||w||}*[-y_i*(w*x_i)] w1[yi(wxi)]。假设误分类点总共为 m m m个,则误所有误分类点到分解面的距离为 ∑ i = 1 m 1 ∣ ∣ w ∣ ∣ ∗ [ − y i ∗ ( w ∗ x i ) ] \sum_{i=1}^{m} \frac {1} {||w||}*[-y_i*(w*x_i)] i=1mw1[yi(wxi)] ,如果不考虑 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} w1,那么损失函数即为: ∑ i = 1 m − y i ∗ ( w ∗ x i ) \sum_{i=1}^{m} -y_i*(w*x_i) i=1myi(wxi)

感知机原始形式

感知机有原始形式和对偶形式,我们先看原始形式。
  原始形式如下:
  感知机原始形式

感知机算法如下:
感知机算法原始算法
可以在步骤(2)之前定义一个boolean变量,判断当前 w w w b b b的情况下是否存在误分类点,误分类点判断逻辑为:遍历所有点,判断 y i ∗ ( w ∗ x i + b ) &lt; = 0 y_i*(w*x_i+b)&lt;=0 yi(wxi+b)<=0是否成立。
例题2.1的python 版本代码实现:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.utils import shuffle


# In[266]:

# examole 2.1
# python版本
x = np.array([[3,3], [4,3], [1,1]])
y = [1, 1, -1]


# In[306]:

"""
np.dot([2,2],[1,1])
4
np.dot([2,2],[[1],[1]])
array([4])
"""
w = [0 ,0]
b = 0
yita = 1


# In[307]:

#是否还存在误分类点
def isHasMisclassification(x, y, w, b):
    misclassification = False
    ct = 0
    misclassification_index = 0 
    for i in range(0, len(y)):
        if y[i]*(np.dot(w, x[i]) + b) <= 0:
            ct += 1
            misclassification_index = i
    if ct>0:
        misclassification = True
    return misclassification, misclassification_index

# In[308]:

# 更新系数w, b
def update(x, y, w, b, i):
    w = w + y[i]*x[i]
    b = b + y[i]
    return w, b


# In[309]:

#更新迭代
import random
def optimization(x, y, w, b):
    misclassification, misclassification_index = isHasMisclassification(x, y, w, b)
    while misclassification:
        print ("误分类的点:", misclassification_index)
        w, b = update(x, y, w, b, misclassification_index)
        print ("采用误分类点 {} 更新后的权重为:w是 {} , b是 {} ".format(misclassification_index, w, b))
        misclassification, misclassification_index = isHasMisclassification(x, y, w, b)
    return w, b


# In[310]:

optimization(x, y, w, b)


# In[311]:

w, b = optimization(x, y, w, b)


# In[312]:

w,b

感知机对偶形式

在这里插入图片描述
感知机对偶形式的算法流程为:
在这里插入图片描述
在这里插入图片描述

对偶形式代码为:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.utils import shuffle


# In[266]:

# examole 2.2 (对偶形式)
# python版本
x = np.array([[3,3], [4,3], [1,1]])
x_transpose = x.T
g = np.dot(x, x_transpose)
y = [1, 1, -1]


# In[306]:

"""
np.dot([2,2],[1,1])
4
np.dot([2,2],[[1],[1]])
array([4])
"""
alfa = np.array([0, 0, 0])
b = 0
yita = 1


# In[307]:

#是否还存在误分类点
def isHasMisclassification(y, g, b):
    misclassification = False
    ct = 0
    misclassification_index = 0
    for i in range(0, len(y)):
        sum1 = 0
        for j in range(0, len(y)):
            sum1 += (alfa[j]*y[j]*g[j][i] + b)
        if y[i]*sum1 <= 0:
            ct += 1
            misclassification_index = i
    if ct > 0:
        misclassification = True
    return misclassification, misclassification_index

# In[308]:

# 更新系数alfa, b
def update(y, alfa, yita, b, i):
    alfa[i] = alfa[i] + yita
    b = b + yita*y[i]
    return alfa, b


# In[309]:

#更新迭代
import random
def optimization(y, alfa, b, yita):
    misclassification, misclassification_index = isHasMisclassification(y, g, b)
    while misclassification:
        print ("误分类的第{}点{}:".format(misclassification_index, x[misclassification_index]))
        alfa, b = update(y, alfa, yita, b, misclassification_index)
        print ("采用第{}误分类点 {} 更新后的权重为:alfa是 {} , b是 {} ".format(misclassification_index, x[misclassification_index], alfa, b))
        misclassification, misclassification_index = isHasMisclassification(y, g, b)
    return alfa, b


# In[310]:

optimization(y, alfa, b, yita)


# In[311]:

alfa, b = optimization(y, alfa, b, yita)


# In[312]:
#w=sum(alfa_i*y_i*x_i)
alfa_y = np.multiply(list(alfa),y)
w = np.dot(alfa_y,x)
b = np.dot(alfa, y)
print("w是{},b是{}".format(w, b))

此次运行结果是:

误分类的第2点[1 1]:
采用第2误分类点 [1 1] 更新后的权重为:alfa是 [0 0 1] , b是 -1 
误分类的第1点[4 3]:
采用第1误分类点 [4 3] 更新后的权重为:alfa是 [0 1 1] , b是 0 
误分类的第2点[1 1]:
采用第2误分类点 [1 1] 更新后的权重为:alfa是 [0 1 2] , b是 -1 
误分类的第2点[1 1]:
采用第2误分类点 [1 1] 更新后的权重为:alfa是 [0 1 3] , b是 -2 
误分类的第1点[4 3]:
采用第1误分类点 [4 3] 更新后的权重为:alfa是 [0 2 3] , b是 -1 
误分类的第2点[1 1]:
采用第2误分类点 [1 1] 更新后的权重为:alfa是 [0 2 4] , b是 -2 
误分类的第2点[1 1]:
采用第2误分类点 [1 1] 更新后的权重为:alfa是 [0 2 5] , b是 -3 
误分类的第2点[1 1]:
采用第2误分类点 [1 1] 更新后的权重为:alfa是 [0 2 6] , b是 -1 
w是[2 0],b是-4

即:分割面为 y = s i g n ( 2 ∗ x 1 − 4 ) y=sign(2*x_1-4) y=sign(2x14),分别带入第0/1/2三个点 ( 3 , 3 ) , ( 4 , 3 ) , ( 1 , 1 ) (3,3),(4,3),(1,1) (3,3),(4,3),(1,1)验证y ( s i g n ( 2 ) , s i g n ( 4 ) , s i g n ( − 2 ) ) (sign(2),sign(4),sign(-2)) (sign(2),sign(4),sign(2)),即label为 ( 1 , 1 , − 1 ) (1,1,-1) (1,1,1)

Ref:
1、李航, 统计学习方法第二章

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值