感知机
在人均深度学习人均神经网络的现在,感知机模型想必大家都比较熟悉了。今天介绍一下在进行感知机分类过程中的权重迭代过程及程序实现。
数据处理
感知机迭代前有些数据处理的操作可以简化原理与程序
二分类
首先需要对特征及系数进行增广
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]