单层感知机

什么是感知机

感知机由Rosenblatt在1957年提出,是一种二类线性分类模型。输入一个实数值的n维向量(特征向量),经过线性组合,如果结果大于某个数,则输出1,否则输出-1.具体地:

其中的w0,w1,....wn权重,W向量称为权向量(本文中粗体代表向量)。权重决定每个输入分类对最终输出的贡献率。为了更简洁地表示,我们加入一个x0=1,则可以将上面的式子写成符号函数(输入大于零的时候为1,其他为-1):

这就是感知机的数学表达,其中W*X为内积,即向量对应元素相乘,然后求和。

感知机原理

e感知n机是二分类的线性模型,其输入是实例的的特征向量,输出的是实例的类别,分别是+1和-1,属于判别模型。假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练数据集正实例点和负实例点完全正确分开的分离超平面。如果是非线性的数据,则最后无法获取超平面。

 

一个简单的单层感知机如下图所示

Python实现单层感知机

step1: 数据生成

在一条直线附近利用np.random.normal产生高斯白噪声,然后生成分布点。这里使用y=k*x+b的形式。然后根据点的分布,给点打上标签是+1还是-1。

'''
利用高斯白噪声生成基于某个直线附近的若干点
y = wb + b
weight 直线权值
bias 直线偏置
size 点的个数
'''
import numpy as np
def random_point_nearby_line(weight,bias,size=10):
    x_point = np.linspace(-1,1,size)[:,np.newaxis]
    noise = np.random.normal(0,0.5,x_point.shape)
    y_point = weight * x_point + bias + noise
    input_arr = np.hstack((x_point, y_point))
    return input_arr

# 直线的真正参数
real_weight = 1
real_bias = 3
size = 100

# 输入数据和标签
# 生成输入的数据
input_point = random_point_nearb_line(real_weight, real_bias, size)
# 给数据打标签,在直线上方还是下方, above = 1, below = -1
label = np.sign(input_point[:,1] - (input_point[:,0] * real_weight + real_bias)).reshape((size,1))

 

step2: 拆分训练集测试集

from sklearn.model_selection import train_test_split
testSize = 15
x_train, x_test, y_train, y_test = train_test_split(input_point, label, test_size=testSize)
trainSize = size - testSize

step3: 绘制初始点与直线

import matplotlib.pyplot as plt
# 将输入点绘图
fig = plt.figure() # 生成一个图片框
ax = fig.add_subplot(111) # 编号
for i in range(y_train.size):
    if y_train[i] == 1:
        ax.scatter(x_train[i,0], x_train[i,1], color='r') # 输入真实值,红色在线上方
    else:
        ax.scatter(x_train[i,0], x_train[i,1], color='b') #输入真实值, 蓝色在线下方

plt.show()

step4: 随机梯度下降法进行训练

#初始化w,b
Weight = np.random.rand(2,1) #随机生成-1到1的一个数据
Bias = 0 #初始化为0
def trainBySGD(input, output, x_test, y_test, test_size,input_num,train_num = 10000, learning_rate=1):
    global Weight, Bias
    x = input
    y = output
    for rounds in range(train_num):
        for i in range(input_num):
            x1, x2 = x[i]
            prediction = np.sign(Weight[0] * x1 + Weight[1] * x2 + Bias)
            #print('prediaction', prediction)
            if y[i] * prediction <= 0: # 判断误分类点
                # Weight = Weight + np.reshape(learning_rate*y[i]*x[i],(2,1))
                Weight[0] = Weight[0] + learning_rate * y[i] * x1
                Weight[1] = Weight[1] + learning_rate * y[i] * x2
        if rounds % 10 == 0:
            learning_rate *= 0.9
            accuracy = compute_accuracy(x_test, y_test, test_size, Weight, Bias)
            print('rounds {}, accuracy {}'.format(rounds,accuracy))

def compute_accuracy(x_test, y_test, test_size, weight, bias):
    x1, x2 = np.reshape(x_test[:,0], (test_size,1)), np.reshape(x_test[:,1],(test_size,1))
    prediction = np.sign(y_test * (x1 * weight[0] + x2 * weight[1] + bias))
    count = 0
    #print('prediaction', prediction)
    for i in range(prediction.size):
        if prediction[i] > 0:
            count = count + 1
    return (count+0.0) / test_size
trainBySGD(x_train, y_train, x_test, y_test, testSize, 85, train_num = 100, learning_rate = 1)

参考链接:

https://blog.csdn.net/bingduanlbd/article/details/24468885

https://www.bilibili.com/video/BV1JE411Y7gB?from=search&seid=10392081171445846990

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值