第1节:感知机perceptron原理与numpy复现

2021-12-02 20:32:37 浏览数 (1)

文章目录
  • 感知机perception
    • 感知机原理
    • 感知机学习策略numpy复现

感知机perception

  • 感知机是最古老的分类方法之一.在1957年就已经提出了.虽然今天看他的分类模型泛化能力不强,但是还是值得去深入研究,因为感知机是神经网络的雏形.
  • 感知机perception是二分类的线性分类模型,输入是实例的特征向量,输出是 1和-1二值.感知机对于输入空间中将实例划分为正负两个类的超平面,属于判别模型.感知机学习过程就是将数据集进行线性瓜分,导入损失函数,并以梯度下降来对损失函数进行极小化,求得感知机模型.
  • 感知机预测就是对训练好的模型进行预测.

感知机原理

  • 假设输入空间是x,x是实例的特征向量,输出空间是y,y的取值范围为{-1, 1}
f(x)=sign(w cdot x b)
sign(x) = {{ 1, xgeq0 atop -1,x<0}

其中w为权值(weight),b为偏置(bias) 这就是感知机模型

  • 感知机前提是假设特征线性可分,超平面s称为分离超平面.

感知机学习策略

  • 数据集的线性可分性
    • 给定一个数据集T={(x_1,y_1),(x_2,y_2),...,(x_n,y_n)}存在一个超平面s w cdot x b=0

    能将正实例和负实例完全正确的分离嫂超平面两侧.则称为线性可分.

  • 学习策略
    • 任意一点x_0到chao平面的距离为d = frac{1}{||w||}|wcdot x_0 b| 错误分类的点无非是将本属于上方的点分到下方,或者本属于下方的点分到上方.则有:|wcdot x_0 b|=-y(wcdot x_0 b) geq 0
    loss = -frac{1}{||w||}displaystyle sum^{i to N}_{x_i}{y(wcdot x_0 b)}
    • 损失函数是非负的,如果没有误分点,损失函数值是0.而且,误分点越少,误分点距离平面越接近,损失函数值越小.
    • 求loss最小,采用随机梯度下降法(stochastic gradient descent)
    L_w=-displaystyle sum^{i to n}_{x_i}{y_ix_i}
    L_b=-displaystyle sum^{i to n}_{x_i}{y_i}
  • 算法形式步骤
    1. 随机赋值,计算误分点;
    2. y_i (w x_i b) leq 0
    3. 极小化过程中不是一次使M中所有误分类点的梯度下降,而是一次随机选取一 个误分类点使其梯度下降。
      1. 迭代w' = w eta y_ix_i
      2. 迭代b' = b eta y_i
    4. 转第1步执行.
  • 感知机的对偶形式
    • 实例 点更新次数越多,意味着它距离分离超平面越近,也就越难正确分类。换句话说,这样的 实例对学习结果影响最大。

numpy复现

代码语言:javascript复制
# -*- coding:utf-8 -*-
# /usr/bin/python
'''
-------------------------------------------------------------------------
   @File Name      :  perception.py
   @Description    :  感知机numpy实现版本
   @Run Script     :  python  perception.py 
   @Envs           :  pip install 
   @Change Activity:
        1.  2021/12/1  下午4:18  : build
-------------------------------------------------------------------------
   @CodeStyle      :  standard, simple, readable, maintainable, and portable!
   @Author         :  Yan Errol 13075851954
   @Email          :  260187357@qq.com
   @Copyright      :  "Copyright 2021, Yan Errol"
-------------------------------------------------------------------------
'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#  类封装
class perception_model():

    def __init__(self,XTrain):
        '''参数定义'''
        self.learning_rate = 0.5
        self.b = 0
        self.w = np.ones(len(XTrain[0]),dtype=np.float32)

    def sign(self,x,w,b):
        '''误点判段'''
        y = np.dot(x, w)   b
        return y

    def fit(self,xTrain,yTrain):
        '''训练'''
        isWrong = False
        while not isWrong:
            wrongNums = 0
            # 错误点判段
            ytest = self.sign(xTrain,self.w,self.b)
            wrongPointIndex = np.where(yTrain*ytest <= 3)
            xWrong,yWrong = xTrain[wrongPointIndex],yTrain[wrongPointIndex]
            wrongNums = len(yWrong)
            if wrongNums == 0: #终止条件判段
                break
            else:
                i = np.random.randint(0,wrongNums)
                x,y = xWrong[i],yWrong[i]
                self.w = self.w   self.learning_rate * np.dot(y, x)
                self.b = self.b   self.learning_rate * y
        return 'Perception train is Done!'

    def predict(self,x):
        '''预测'''
        y = np.dot(x, self.w)   self.b
        print("y",y)
        if y > 0:
            y = 1
        else:
            y = 0
        return y

# 数据加载
data = pd.read_csv("dataset.csv")
print(data.label.value_counts())
print("datan",data)

# 数据可视化 验证线性可分性
plt.scatter(data[:50]['sepal length'], data[:50]['sepal width'], label='0')
plt.scatter(data[50:100]['sepal length'], data[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
plt.savefig("show.png")

# 数据集拆分
data = np.array(data.iloc[:100,[0,1,-1]])
XTrain,Ytrain = data[:-1,:-1],data[:-1,-1]
Xtest,Ytest = data[-1, : -1], data[-1, -1]

# 训练
perception = perception_model(XTrain)
perception.fit(XTrain,Ytrain)
yPredict = perception.predict(Xtest)
print(yPredict,Ytest)

0 人点赞