统计学习笔记-导论 感知机算法原始、对偶形式 原理、python实现

文章中的截图均来自李航老师的《统计学习方法》一书。

1.过拟合产生的原因以及造成的影响

统计学习有3个要素,模型、策略以及算法。给定一组数据集,需要通过模型对数据的分布进行拟合。先把原始的数据集划分为训练集、验证集和测试集,训练集用来对模型的参数进行更新,测试集用来衡量训练好的模型的性能。如果模型在训练集上的准确率很高、在测试集上的准确率很低,那么说明发生了过拟合,即模型对训练集拟合的过好了。造成的影响就是模型的泛化能力低,模型对于训练集以外的数据很难拟合。就相当于为了准备考试,使劲刷题,题库里(训练集)的题目都做对了,但是真正考试的时候(测试集)却得分很低,题库外的题就做不对了。

2.极大似然估计要解决一个什么问题呢

已知一系列的样本以及样本的符合某种概率分布函数,但是分布函数中的一些参数是未知的,通过这些样本来估计概率分布函数的未知的参数。
求解步骤:求似然函数的导数,对似然函数取对数并求导,令导数为0,目的是为了下溢出。
贝叶斯估计:就是待估计的参数的某些统计量是已知的,比如符合某种分布,相比较于极大似然估计,对待估计的参数又确定了一丢丢。

3.感知机是什么?应用场景是什么?假设空间是什么?

感知机是机器学习算法的基石,很基础也很简单。
感知机的只能从处理线性可分的问题,只能处理二分类问题。通过构造一个超平面,将样本分为两类。对于线性不可分的问题,感知机是没法处理的。
感知机的对偶形式会使得求解的过程大大地化简。
某个算法的对偶形式肯定可以将原来的算法的复杂度降低,或者说原来的问题是不可以求解的,使用对偶形式以后,问题可以变得求解了。

4.感知机原始形式以及python实现

4.1原始形式算法描述

algorithm convergence感知机是误分类驱动的,要找到感知机的误分类的上界。明白在什么条件下,感知机是有用的?

4.2 原始形式Python代码实现

Input:[3,3,1],[4,3,1],[1,1,-1]三个样本点
Output:感知机分离超平面
初始值: w = [ w 1 , w 2 ] T = [ 0 , 0 ] T w=[w_1,w_2]^T=[0,0]^T w=[w1,w2]T=[0,0]T; b=0; η = 1 \eta=1 η=1; epoch number = 10

## 感知机原始形式的求解 ##
import numpy as np 
import pandas as pd 
import time
if __name__ == '__main__':
    # 建立训练集
    time_start= time.time()
    x1 = [3,3,1]
    x2 = [4,3,1]
    x3 = [1,1,-1]
    data = np.array([x1,x2,x3]).reshape(3,-1)
    x_image = data[:,:-1] # 获得训练集中的特征值
    x_label = data[:,-1]  # 获得训练集数据的标签值
    # 参数初始化,w,b是需要进行梯度更新的
    w = [0,0]
    b = 0
    lr = 1
    # 训练周期
    epoch = 10

    for epoch_num in range(epoch):
        for i in range(np.size(x_label)):
            loss = x_label[i]*(np.dot(w,x_image[i]) + b) #计算该点是否被误分类,然后进行梯度下降
            if loss <= 0:
                w = w + lr*x_label[i]*x_image[i]
                b = b+lr*x_label[i]
            loss = 0
        print('[Epoch num: %d] [W: %s] [b:%.4f]' % (epoch_num,str(w),b))  
        print('-----------------------------------------------')
    time_end = time.time()
    runing_time = time_end -time_start

    print('Finised Training')
    print('w:',w)
    print('b:',b)
    print('Running Time: %.5f s' % runing_time)

运行结果得到:
在这里插入图片描述

5 感知机对偶形式以及Python实现

5.1 对偶形式算法描述

在这里插入图片描述

5.2 对偶形式的Python代码实现

Input:[3,3,1],[4,3,1],[1,1,-1]三个样本点
Output:感知机分离超平面
初始值: α = [ α 1 , α 2 , α 3 ] T = [ 0 , 0 , 0 ] T \alpha=[\alpha_1,\alpha_2,\alpha_3]^T=[0,0,0]^T α=[α1,α2,α3]T=[0,0,0]T; b=0; η = 1 \eta=1 η=1; epoch number = 10

## 感知机对偶形式的求解 ##
import numpy as np 
import pandas as pd 
import time

if __name__ == '__main__':
    # 建立训练集
    time_start= time.time()
    x1 = [3,3,1]
    x2 = [4,3,1]
    x3 = [1,1,-1]
    data = np.array([x1,x2,x3]).reshape(3,-1)
    x_image = data[:,:-1]            # 获得训练集中的特征值
    x_label = data[:,-1]             # 获得训练集数据的标签值
    gram = np.dot(x_image,x_image.T) # 计算gram矩阵
    alpha = np.zeros(3)
    print(alpha)
    b = 0
    lr = 1
    epoch = 10

    for epoch_num in range(epoch):
        for i in range(np.size(x_label)):
            loss1 =np.dot(alpha*x_label, gram[:, i])
            loss1 = loss1 + b
            #print(loss1)
            #print(x_label[i]*loss1)
            cond = x_label[i] * loss1
            if cond <= 0:
                alpha[i] = alpha[i] + lr  # 昨天在写这个模块的时候,更新的地方写错了,少了i;对应的是每一个样本的alpha_i进行更新;
                b = b + lr*x_label[i]
        cond = 0
        print('[Epoch num: %d] [Alpha: %s] [b:%.4f]' % (epoch_num,str(alpha),b)) 
        print('-----------------------------------------------') 
    time_end = time.time()
    running_time = time_end - time_start 
    print(alpha)   
    print(b)
    # 计算w,b得到分类器的表达式
    w = np.dot(x_label*alpha,x_image)
    print('-------------------')
    print('The weight w is: %s'%(str(w)))
    print('The bias b is: %f' % (b))
    print('Running Time:%.5f s'%(running_time))
    

运行结果
在这里插入图片描述

6 使用sklearn实现感知机

主要包括:导入库,喂数据,训练分类器

## 使用的是sklearn 实现感知机
## 流程大概是:导入库,喂数据,fit训练分类器

from sklearn.linear_model import Perceptron
x_train =  data[:,:-1] # 获得训练集中的特征值
print(x_train)
y_train = data[:,-1]   # 获得训练集数据的标签值

classifier = Perceptron(fit_intercept=False,max_iter=10,shuffle=False)
classifier.fit(x_train,y_train)

print('The weighit is: %s'%(str(classifier.coef_)))
print('The bias is : %s'%(str(classifier.intercept_)))

结果:
在这里插入图片描述

7 总结

使用sklearn是最方便的一个,你需要做的就是处理数据,sklearn把基本的框架都给你搭建好了。自己在学习的时候,最好亲手用Python写一下,梯度怎么更新的,数据怎么存储的,怎么查找到你想要的数据,矩阵怎么相乘,亲手实现一遍会对原理的理解更上一个层次,在这个过程中踩坑是不可避免的。

8回顾

又重新手打了一遍代码

## 感知机模型的实现
import numpy as np
import time
import matplotlib.pyplot as plt

class Perceptron:
    def __init__(self):
        self.delta = 0.5
        self.w = None
        self.b = 0

    def fit(self, x_train, y_train):
        self.w = np.array([1]*x_train.shape[1])
        x_image = x_train
        y_label = y_train
        for loop in range(10):                                       ## loop是遍历数据集的次数,这个表示把数据集用几次来更新模型的参数
            for i in range(x_image.shape[0]):
                condition = y_train[i]*(np.dot(x_train[i],self.w) + self.b) 
                if condition <= 0:
                    self.w = self.w + self.delta*y_train[i]*x_train[i] #必须是+,在李航的书中更新时候也是+,
                    # 为什么是-的时候,就不可以呢?讲道理的话,只是一个符号的作用啊
                    self.b = self.b + self.delta*y_train[i]
                else:
                    self.w = self.w
                    self.b = self.b
            loop += loop
        return self.w,self.b

    def predict(self,x_test):
        test_image = x_test
        condi = np.dot(test_image, self.w) + self.b
        if condi>=0:
            print('The predict label is: 1')
        else:
            print('The test label is : 0')

def draw(x,y):
    for i in range(x.shape[0]):
        if y[i] >= 0:
            plt.scatter(x[i][0],x[i][1],color = 'r',marker='*')
        else:
            plt.scatter(x[i][0],x[i][1])

        


if __name__ == '__main__':
    x1 = [3,3,1]
    x2 = [4,3,1]
    x3 = [1,1,-1]
    data = np.array([x1,x2,x3]).reshape(3,-1)
    x_image = data[:,:-1] # 获得训练集中的特征值
    x_label = data[:,-1]  # 获得训练集数据的标签值
    x_test = np.array([1,1.5])

    clf = Perceptron()
    w,b = clf.fit(x_image,x_label)
    clf.predict(x_test)
    print(w,b)
    draw(x_image,x_label)
    x = np.linspace(0,4,20)
    y_ =(-w[0]*x-(b))/w[1]  ## 画出分离超平面
    plt.plot(x,y_)

运行结果:
在这里插入图片描述

Talk is cheap, show me your code.

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值