感知机划分二维平面xdu机器学习实验一

原理很简单,网上讲解铺天盖地,找两个看得懂的贴上:
《统计学习方法》第二章感知机
感知机算法详解
主要理解其损失函数,以及对其求导,这样就能迭代出更新权重 w w w和常数 b b b
要求:生成四个高斯分布的数据,逻辑与的二分类形式。即(1,1)为正分类,(0,0),(0,1),(1,0)分布的点是负类。然后求出一条直线划分即可。
算法核心:
即更新权重。每一轮我们都判断所有的点是否和划分的类一样,假如不一样就更新权重:
w ← w + η y i x i b ← w + η y i w←w+ηy_{i} x_{i}\\b←w+ηy_{i} ww+ηyixibw+ηyi
但是有时数据过于分散就会永远划分不出一条能完全分开的线,所以我们循环100轮​就结束:

	# 定义训练函数,训练集input_vecs,标签集labels,学习率rate
    def train(self, input_vecs, labels, rate):

        round = 0  # 迭代次数
        while(True):
            if(round>100):break;#陷入死循环
            round+=1
            round_errors=0

            for input_vec, label in zip(input_vecs, labels):
                if (sum(np.array(input_vec) * self.weights) + self.bias)*label <= 0:
                    round_errors+=1
                    # 更新权重
                    self.weights += rate * np.array(input_vec) * label
                    self.bias += rate*label
                    #print('g(x) = {} * x1 + {} * x2 + {}'.format(self.weights[0], self.weights[1], self.bias))

            print("第{}轮中,训练错误数:样本数量={}:{}".format(round, round_errors, len(input_vecs)))
            if round_errors==0:
                break;

细枝末节详见源代码。效果如下:
demo
源码如下:

import numpy as np
import matplotlib.pyplot as plt

class Perception(object):
    # 初始化权重
    def __init__(self):
        self.weights = np.random.random()
        self.bias = 0

    # 定义训练函数,训练集input_vecs,标签集labels,学习率rate
    def train(self, input_vecs, labels, rate):

        round = 0  # 迭代次数
        while(True):
            if(round>100):break;#陷入死循环
            round+=1
            round_errors=0

            for input_vec, label in zip(input_vecs, labels):
                if (sum(np.array(input_vec) * self.weights) + self.bias)*label <= 0:
                    round_errors+=1
                    # 更新权重
                    self.weights += rate * np.array(input_vec) * label
                    self.bias += rate*label
                    #print('g(x) = {} * x1 + {} * x2 + {}'.format(self.weights[0], self.weights[1], self.bias))

            print("第{}轮中,训练错误数:样本数量={}:{}".format(round, round_errors, len(input_vecs)))
            if round_errors==0:
                break;

        return self.weights, self.bias ,round

def show(x,y):
    plt.scatter(x, y, s=20)
    plt.title('perceptron', fontsize=24)

    plt.xlabel('x')
    plt.ylabel('y')
    my_x_ticks = np.arange(0,1.5, 0.5)
    my_y_ticks = np.arange(0,1.5, 0.5)
    plt.xticks(my_x_ticks)
    plt.yticks(my_y_ticks)

    plt.show()


if __name__ == '__main__':
    #生成数据
    n=2
    sample_num=300
    sigma=0.012;
    cov=sigma*np.identity(n)
    mean=[[1,1],[1,0],[0,1],[0,0]]
    inputt=[]
    for i in range(4):
        inputt.append(np.random.multivariate_normal(mean[i],cov,sample_num))
    inputdata=np.vstack((inputt[0],inputt[1],inputt[2],inputt[3]))

    x,y=inputdata.T
    #show(x,y)

    #生成标签
    labels=np.zeros(4*sample_num)
    for i in range(4):
        for j in range(sample_num):
            if i :
                labels[i*sample_num+j]=-1
            else:
                labels[i * sample_num + j] = 1

    rate=0.1#学习率(决定步长)
    p=Perception()
    p.train(inputdata,labels,rate)
    px=np.array([0,2])
    py=np.zeros(2)
    for i in range(len(px)):
        py[i]=(p.weights[0]/p.weights[1]*px[i]+p.bias/p.weights[1])*(-1)
    plt.plot(px,py)
    plt.text(0.5, 1, 'sigma={}'.format(sigma),fontsize=16)
    show(x,y)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值