Python实现二分类及多分类感知机

感知机

在人均深度学习人均神经网络的现在,感知机模型想必大家都比较熟悉了。今天介绍一下在进行感知机分类过程中的权重迭代过程及程序实现。

数据处理

感知机迭代前有些数据处理的操作可以简化原理与程序

二分类

首先需要对特征及系数进行增广
x = [ x 1 , x 2 , . . . , x n , 1 ] ω = [ ω 1 , ω 2 , . . . , ω n , b ] \text{x}=[x_1,x_2,...,x_n,1] \\ \omega = [{\omega_1},{\omega_2},...,{\omega_n},b] x=[x1,x2,...,xn,1]ω=[ω1,ω2,...,ωn,b]
则训练时可以认为
ω T x > 0   x ∈ ω 1 ω T x < 0   x ∈ ω 2 \omega^T\text{x}>0 \ x \in \omega_1\\ \omega^T\text{x}<0 \ x \in \omega_2 ωTx>0 xω1ωTx<0 xω2
同时为了训练时有统一的形式,我们给 x ∈ ω 2 x\in\omega_2 xω2的特征乘以 − 1 -1 1,则当 ω T x > 0 \omega^T\text{x}>0 ωTx>0代表正确分类,反之分类错误。

多分类

多分类时要求对应类的 ω i T x \omega_i^T\text{x} ωiTx最大,只进行增广就行了。

程序

# @Time    : 2021/9/30 22:49
# @Author  : AlanLiang
# @FileName: perceptron.py
# @Software: VS Code
# @Github  :https://github.com/AlanLiangC
# @Mail    : liangao21@mails.ucas.ac.cn
import textwrap
import numpy as np
import copy

# 定义感知机的类,可解决二类及多类问题
class Perceptron():
    def __init__(self,feature_V):
        self.feature_V = copy.deepcopy(feature_V)
        self.class_num = len(feature_V)
        self.C = 1
        self.w = np.zeros([feature_V[0].shape[1]+1,1]) # w是列向量

    # 将特征矩阵变为增广矩阵
    def augmented(self):
        for i in range(len(self.feature_V)):
            self.feature_V[i] = np.c_[self.feature_V[i],np.ones([self.feature_V[i].shape[0],1])]
        return self.feature_V

    # 解决二分类问题的感知机模型
    def two_Classification(self):
        # 进行特征矩阵的增广
        first_class = self.feature_V[0]
        first_class = np.c_[first_class,np.ones([first_class.shape[0],1])]
        second_class = self.feature_V[1]
        second_class = -1*np.c_[second_class,np.ones([second_class.shape[0],1])]
        # 垂直拼接两类特征向量至同一矩阵中
        all_class = np.vstack([first_class,second_class])
        print(all_class)
        time_result = np.zeros(all_class.shape[0])
        while(np.any(time_result <= 0)):
            for i in range(all_class.shape[0]):
                time_result[i] = np.dot(self.w.T,all_class[i,:].reshape([all_class.shape[1],1]))
                if time_result[i] > 0 :
                    continue
                else:
                    self.w += self.C*all_class[i,:].reshape([all_class.shape[1],1])
        print(self.w)
        return self.w

    # 解决多分类问题的感知机模型   
    def multi_Classification(self):
        # 首先对特征矩阵进行增广
        self.feature_V = self.augmented()
        w = np.zeros([len(self.feature_V),self.feature_V[0].shape[1],1])
        result = np.zeros(len(self.feature_V))
        while(True):
            for i in range(len(self.feature_V)):
                this_class = self.feature_V[i]
                this_result = np.zeros(this_class.shape[0])
                other_list = [m for m in range(len(self.feature_V))]
                other_list.pop(i)
                for j in range(this_class.shape[0]):
                    this_ans = np.dot(w[i,:,:].T,this_class[j].reshape([this_class.shape[1],1]))
                    add_num = 0
                    for k in other_list:
                        other_ans = np.dot(w[k,:,:].T,this_class[j].reshape([this_class.shape[1],1]))
                        if this_ans > other_ans :
                            this_result[j] = 1
                        else:
                            if add_num == 0:
                                w[i,:,0] += self.C * this_class[j,:]
                                w[k,:,0] -= self.C * this_class[j,:]
                                add_num += 1
                            else:
                                w[k,:,0] -= self.C * this_class[j,:]
                if np.any(this_result > 0):
                    result[i] = 1
            if np.any(result > 0):
                break
        print(w)

    # 总执行函数,判断输入特征的分类数选择执行不同的子函数
    def get_result(self):
        if self.class_num == 2:
            self.two_Classification()
        elif self.class_num > 2:
            self.multi_Classification()
        else:
            print("导入数据格式错误!")

# 二分类感知机测试
# first_class = np.array([[0,0,0],[1,0,0],[1,0,1],[1,1,0]])
# second_clss = np.array([[0,0,1],[0,1,1],[0,1,0],[1,1,1]])
# feature_V = [first_class,second_clss]
# test = Perceptron(feature_V)
# test.get_result()


# 多分类感知机测试
first_class = np.array([[-1,-1]])
second_class = np.array([[0,0]])
third_class = np.array([[1,1]])
feature_V = [first_class,second_class,third_class]
test = Perceptron(feature_V)
test.get_result()

测试

读者可自行测试,测试程序也有给出,可对自己的需求修改特征向量,输出即为各类的线性方程系数 ω = [ ω 1 , ω 2 , . . . , ω n , b ] \omega = [{\omega_1},{\omega_2},...,{\omega_n},b] ω=[ω1,ω2,...,ωn,b]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值