感知器
感知器是一种人工神经网络,其模拟生物上的神经元结构 感知器是一个二分类器,其将净输入为:
z
=
W
T
X
=
w
0
+
w
1
x
1
+
w
2
x
2
+
⋯
+
w
n
x
n
z=W^{T}X=w^{0}+w^{1}x^{1}+w^{2}x^{2}+\cdots+w^{n}x^{n}
z = W T X = w 0 + w 1 x 1 + w 2 x 2 + ⋯ + w n x n
通过激活函数
φ
(
z
)
\varphi(z)
φ ( z ) ,就可以将其映射为1或-1
φ
(
z
)
=
{
1
z
≥
θ
−
1
z
<
θ
\varphi(z)=\begin{cases} 1 & z\geq \theta \\ -1 & z<\theta \end{cases}
φ ( z ) = { 1 − 1 z ≥ θ z < θ 其中
θ
\theta
θ 是我们指定的一个值
import numpy as np
import pandas as pd
data= pd. read_csv( r"F:\数据集\Iris数据集\iris.csv" )
data. drop( "Unnamed: 0" , axis= 1 , inplace= True )
data. drop_duplicates( inplace= True )
data[ "Species" ] = data[ "Species" ] . map ( { "versicolor" : 0 , "virginica" : 1 , "setosa " : - 1 } )
data= data[ data[ "Species" ] != 0 ]
len ( data)
99
编写感知器类
class Perception :
"""
使用python语言实现感知器算法,实现二分类
"""
def __init__ ( self, alpha, times) :
"""
初始化方法:
Parameters:
-------------
alpha:float
学习率
times:int
最大迭代次数
"""
self. alpha= alpha
self. times= times
def step ( self, z) :
"""
阶跃函数
Paraneters:
-------------------
z:数组类型。(或者是标量类型)
阶跃函数的参数,可以跟据z值,返回1或-1(这样可以实现二分类)
Return:
-------------
value:int
如果z>=0,返回1,否则返回-1
"""
return np. where( z>= 0 , 1 , - 1 )
def fit ( self, X, y) :
"""
根据提供的训练数据,对模型进行训练
Parameters
-------------
X:类数组类型。形状:[样本数量,特征数量]
待训练的样本数据。
y:类数组类型。形状:[样本数量]
每个样本的目标值。(分类)
"""
X= np. asarray( X)
y= np. asarray( y)
self. w_= np. zeros( 1 + X. shape[ 1 ] )
self. loss_= [ ]
for i in range ( self. times) :
loss= 0
for x, target in zip ( X, y) :
y_hat= self. step( np. dot( x, self. w_[ 1 : ] ) + self. w_[ 0 ] )
loss+= y_hat!= target
self. w_[ 0 ] += self. alpha* ( target- y_hat)
self. w_[ 1 : ] += self. alpha* ( target- y_hat) * x
self. loss_. append( loss)
def predict ( self, X) :
"""
根据参数传递的样本,对样本数据进行预测。(1或-1)
Parameters:
--------------
X:类数组类型,形状为:[样本数量,特征数量]
待预测的样本特征。
Returns:
---------------
result:数组类型
预测的结果值(分类值1或-1)
"""
return self. step( np. dot( X, self. w_[ 1 : ] ) + self. w_[ 0 ] )
测试与可视化
t1= data[ data[ "Species" ] == 1 ]
t2= data[ data[ "Species" ] == - 1 ]
t1= t1. sample( len ( t1) , random_state= 0 )
t2= t2. sample( len ( t2) , random_state= 0 )
train_X= pd. concat( [ t1. iloc[ : 40 , : - 1 ] , t2. iloc[ : 40 , : - 1 ] ] , axis= 0 )
train_y= pd. concat( [ t1. iloc[ : 40 , - 1 ] , t2. iloc[ : 40 , - 1 ] ] , axis= 0 )
test_X= pd. concat( [ t1. iloc[ 40 : , : - 1 ] , t2. iloc[ 40 : , : - 1 ] ] , axis= 0 )
test_y= pd. concat( [ t1. iloc[ 40 : , - 1 ] , t2. iloc[ 40 : , - 1 ] ] , axis= 0 )
p= Perception( 0.1 , 10 )
p. fit( train_X, train_y)
result= p. predict( test_X)
display( result)
display( test_y. values)
display( p. w_)
display( p. loss_)
array([1, 1, 1, 1, 1, 1, 1, 1, 1])
array([1., 1., 1., 1., 1., 1., 1., 1., 1.])
array([0., 0., 0., 0., 0.])
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
import matplotlib as mpl
import matplotlib. pyplot as plt
mpl. rcParams[ "font.family" ] = "SimHei"
mpl. rcParams[ "axes.unicode_minus" ] = False
plt. plot( test_y. values, "go" , ms= 15 , label= "真实值" )
plt. plot( result, "rx" , ms= 15 , label= "预测值" )
plt. title( "感知器-二分类" )
plt. xlabel( "样本序号" )
plt. ylabel( "类别" )
plt. legend( )
plt. show( )
plt. plot( range ( 1 , p. times+ 1 ) , p. loss_, "o-" )
[<matplotlib.lines.Line2D at 0x4c13bb7c08>]