【李航-统计机器学习】【原理及代码】【第二章】 感知机模型 python C++

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_36923418/article/details/88999465

一、原理

      感知机的“非对偶”还是比较容易理解的,输出的Y只有 +1 和 -1 两个选择。

       公式:,其中w是权重,b是偏置

       其中sign算是个激活函数:

                        

      线性方程:   这个对应空间中的一个超平面

                                              

     需要知道的几个小内容:

      1、点到超平面的距离:

          ,这样一来相当于是x向量在w方向上投影之后+b = 距离

       2、误分类数据,具有如下关系成立:

                              

       3、误分类点到超平面的总距离:

                                

       4、损失函数:

                               

                                      

       5、参数更新:

                                          

二、课本上2.1 的习题

         

import numpy as np
import random
#定义数据
#define data
#positive point
x1=[3,3]
x2=[4,3]
#negtive point
x3=[1,1]
#定义模型,定义负样本的随机选择(遵从随机梯度下降)
#define model
#f(x)=sign(wx+b)

def sign(y_):
    if y_>= 0:
        return 1
    if y_<0:
        return -1
class perceptron_model:
    def __init__(self,w,b,lr):
        #初始化 Initialization
        self.w=w
        self.b=b
        self.lr=lr
    def forward(self,x):
        return self.w[0]*x[0]+self.w[1]*x[1]+self.b
    def backward(self,x,y):
        self.w[0]=self.w[0]+self.lr*y*x[0]
        self.w[1]=self.w[1]+self.lr*y*x[1]
        self.b=self.b+self.lr*y
    def loss(self,preds,labels):
        loss_=0
        for pred,label in zip(preds,labels):
            if -label *  pred >= 0:
                #loss_+= -label*pred   #正统loss
                loss_+=1              #非正统
        return loss_
        
def get_preds(model,data):
    preds=[]
    for x0,x1 in data:
        preds.append(model.forward([x0,x1]))
    return preds
def stochastic_select_negtive_data(data,preds,labels):
    new_data=[]
    for point,pred,label in zip(data,preds,labels):
        if -label*pred >=0:
            new_data.append([point,label])
    selected_data=random.sample(new_data,1)
    return selected_data
#学习,训练模型
meta=[x1,x2,x3]
labels=[1,1,-1]
model=perceptron_model(w=[0,0],b=0,lr=1)
preds=get_preds(model,meta)
print(preds)
loss_=model.loss(preds,labels)
while loss_>0:
    selected_data=stochastic_select_negtive_data(meta,preds,labels)
    print(selected_data)
    model.backward(selected_data[0][0],selected_data[0][1])
    preds=get_preds(model,meta)
    loss_=model.loss(preds,labels)


#第一次预测结果
[0,0,0]
#打印出每次选择的负样本
[[[3, 3], 1]]
[[[1, 1], -1]]
[[[1, 1], -1]]
[[[1, 1], -1]]
[[[3, 3], 1]]
[[[1, 1], -1]]
[[[1, 1], -1]]
#查看模型参数与预测结果
print(model.w,model.b)
print(get_preds(model,meta))

([1, 1], -3)
[3, 4, -1]

结果与课本上一致:

后期更新C++代码。。。

猜你喜欢

转载自blog.csdn.net/github_36923418/article/details/88999465