学习笔记-《统计学习方法》-第二章-感知机

2 感知机

2.1 感知机模型

假设输入空间(特征空间)是χRn,输出空间是γ={+1,1},输入xχ表示实例的特征向量,对应于输入空间的点;输出yγ表示实例的类别,由输入到输出的如下函数

f(x)=sign(ωx+b)

称为感知机。其中ωb为感知机模型参数。

2.2 学习策略

  • 线性可分数据集:如果存在超平面S

    ωx+b=0

    能够将数据集的正实例点和负实例点完全正确的划分到超平面的两侧,则称数据集为线性可分数据集(linearly separable data set)

  • 由于空间Rn中任意一点到超平面S的距离是

    1||ω|||ωx0+b|

    所有误分类点到超平面的总距离为

    1||ω||xiMyi(ωxi+b)

2.3 学习算法

2.3.1 原始形式

输入:训练数据集T=(x1,y1),(x2,y2),...,(xN,yN),其中xiX=Rn,yiy=1,+1,i=1,2,..,N;学习率η(0<η1)

输出:wi,bi感知机模型f(x)=sign(wx+b)

(1)选取初值w0,b0

(2)在训练集中选取数据(xi,yi)

(3)如果yi(wxi+b)0

ww+ηyixibb+ηyi

(4)转至(2),直至数据没有误分类点

2.3.2 算法收敛性的证明

首先将偏置b也并入权重向量w,记做w^=(wT,b)T,同样也将输入向量加以补充,加进常数1,记做x^=(xT,1)T,这样x^Rn+1,w^Rn+1,显然,w^x=wx+b

Novikoff定理
设训练数据T=(x1,y1),(x2,y2),...,(xN,yN)是线性可分,其中xiX=Rn,yiy=1,+1,i=1,2,..,N,则

(1)存在满足条件||w^opt||=1的超平面w^optx^=woptx+bopt=0将训练集数据完全分开;且存在γ>0,对所有i=1,2,...,N

yi(w^optxi)=yi(woptxi+bopt)γ

(2)令R=max1iN||x^i,则感知机算法在训练数据集上的误分类次数k满足不等式

k(Rγ)2

证明:

(1)由于数据集是线性可分的,按照定义存在超平面可以将数据集完全正确分开,取超平面为w^optx^=woptx+bopt=0,并使||w^opt||=1,因此对于有限的i,均有

yi(w^optxi)=yi(woptxi+bopt)>0

所以存在γ

γ=mini{yi(woptxi+bopt)}

满足

yi(w^optxi)=yi(woptxi+bopt)γ

(2)令w^k1是第k个误分类实例之前的扩充权重向量,即

w^k1=(wk1T,bk1)T

k个误分类实例的条件是

yi(w^k1xi)=yi(wk1xi+bk1)0

(xi,yi)是被误分类的数据,则

w^k=w^k1+ηyix^i

由此,推导两个不等式

(2.12)w^kw^optkηγ

由之前的式子可知

w^kw^opt=w^k1w^opt+ηyiw^optx^iw^k1w^opt+ηγ

进一步递推得到

w^kw^optw^k1w^opt+ηγw^k2w^opt+2ηγ...kηγ

下一步证明

(2.13)||w^k||kη2R2

由前面的式子可得

||w^k||2=||w^k1||2+2yiw^k1x^i+η2||x^i||2||w^k1||2+η2||x^i||2||w^k1||2+η2R2||w^k2||2+2η2R2...kη2R2

结合2.12和2.13可得

kηγw^kw^opt||w^k|| ||w^opt||=||w^k||kηRk2γ2kR2

所以得到

k(Rγ)2

最终证明误分类次数存在上界,经过有限次搜索可以找到将训练数据完全正确分开的分离超平面。也就是说,当数据线性可分时,感知机算法是收敛的。

习题

2.1

假设二维平面,存在四个点,(1,1)、(1,-1)、(-1,1)、(-1,-1),根据异或的定义,(1,1)和(-1,-1)应被归为一类,但从二维空间看,并不存在这样一个平面,可以将这4个点,依据正负样本分隔开。

2.3

必要性:

样本线性可分->正实例点所构成的凸壳与负实例点所构成的凸壳互不相交

采用反证法

假设样本集线性可分,正实例点所构成的凸壳与负实例点所构成的凸壳相交,即存在某个元素s,同时满足sconv(S+)sconv(S)

首先样本线性可分,代表存在一个超平面wx+b=0,使得正、负实例处于超平面的两边,即对于所有的正实例来说,满足

wxi+b=ϵi>0,i=1,2,...,|S+|

根据凸壳的定义,对于conv(S+)中的元素,存在

ws++b=wi=1|S+|λixi+b=i=1|S+|λiwxi+b=i=1|S+|λi(ϵib)+b=i=1|S+|λiϵi>0

同理,对于conv(S)中的元素,均存在

ws+b==i=1|S|λiϵi<0

那根据推理,不存在s同时满足sconv(S+)sconv(S)

充分性有点纠结...没有发现好理解的证明

感知机原始形式代码实现:

# 感知机的原始形式
import numpy as np

X = np.array([[3,3], [4,3], [1,1]]).T
y = np.array([1,1,-1]).T

# 构建模型
def predict(w, b, x):
    f = np.dot(w , x) + b
    return 1 if f > 0 else -1 

# 模型训练
def train(lr=1):
    # 初始化
    w = np.array([0, 0]) 
    b = 0
    lr = lr
    
    false_count = len(X)    
    iter_count = 0
    # 迭代
    while false_count != 0:
        print(f"this is the {iter_count}th iter")
        false_count = X.shape[1]
        for x_p, y_p in zip(X.T, y):
            print(f'the train set is {x_p}, {y_p}')
            pre_y = predict(w, b, x_p)
            # print(pre_y)
            if pre_y * y_p <= 0:
                w = w + lr * y_p * x_p
                b = b + lr * y_p 
                print(w, b)
            else:
                false_count -= 1
                print(f'false_count:{false_count}')
        iter_count += 1

train()

感知机对偶形式代码实现

# 生成gram矩阵
def calculate_gram_matrix(X):
    # 矩阵中不同样本是列向量
    gram_matrix = np.dot(X.T, X)
    return gram_matrix

# 
def duality_predict(alpha, b, x_i, gram_matrix_p):
    n = len(gram_matrix_p) 
    res = 0
    for j, x_j_x_i in enumerate(gram_matrix_p):
        res += alpha[j] * y[j] * x_j_x_i
    
    res += b
    return res

def duality_train():
    # 初始化
    alpha = np.array([0, 0, 0]) 
    b = 0
    
    false_count = len(X)    
    iter_count = 0
   
    gram_matrix = calculate_gram_matrix(X)
    # 迭代
    while false_count != 0:
        print(f"this is the {iter_count}th iter")
        false_count = X.shape[1]
        
        for i, (x_i, y_i) in enumerate(zip(X.T, y)):
            print(f'the train set is {x_i}, {y_i}')
            pre_y = duality_predict(alpha, b, x_i, gram_matrix[i])
            # print(pre_y)
            if pre_y * y_i <= 0:
                alpha[i] += 1
                b += y_i
                print(alpha, b)
            else:
                false_count -= 1
                print(f'false_count:{false_count}')
        iter_count += 1
    
    w = 0
    for i, x_i in enumerate(X):
        w += alpha[i] * y[i] * X[:,i]
     
duality_train()
posted @   zoro-zhao  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)
点击右上角即可分享
微信分享提示