Perceptron:二类分类的线性分类模型,输入为实例的特征向量,输出为实例的类别。对应于输入空间(特征空间)中将实例划分为正负两类的分离超平面,属于判别模型。
1 感知机模型
定义 假设输入空间(特征空间)是
X
⊆
R
n
\mathscr{X}\subseteq \mathbf{R}^n
X⊆Rn,输出空间是
Y
=
{
+
1
,
−
1
}
\mathscr{Y}=\{+1,-1\}
Y={+1,−1}。输入
x
⃗
∈
X
\vec x \in \mathscr{X}
x∈X表示实例的特征向量,对应于输入空间(特征空间)的点;输出
y
∈
Y
y \in \mathscr{Y}
y∈Y表示实例的类别。由输入空间到输出空间的如下函数:
f
(
x
)
=
s
i
g
n
(
w
⃗
⋅
x
⃗
+
b
)
f(x) = sign(\vec w \cdot \vec x + b)
f(x)=sign(w⋅x+b)
称为感知机。其中,w和b为感知机模型参数,
w
⃗
∈
R
n
\vec w \in \mathbf{R}^n
w∈Rn叫做权值(weight)或权值向量(weight vector),
b
∈
R
b \in \mathbb{R}
b∈R叫做偏置(bias),
w
⃗
⋅
x
⃗
\vec w \cdot \vec x
w⋅x为内积,sign是符号函数。
假设空间:定义在特征空间中的所有线性分类模型,即函数集合 { f ∣ f ( x ) = w ⃗ ⋅ x ⃗ + b } \{f|f(x)=\vec w \cdot \vec x + b\} {f∣f(x)=w⋅x+b}。
2 感知机学习策略
2.1 数据集的线性可分性
存在一个分离超平面 w ⃗ ⋅ x ⃗ + b = 0 \vec w \cdot \vec x +b=0 w⋅x+b=0能够将数据集的正实例点和负实例点完全正确地划分到超平面的两侧。即 ( w ⃗ ⋅ x ⃗ i + b ) × y i > 0 (\vec w \cdot \vec x_i + b) \times y_i > 0 (w⋅xi+b)×yi>0。
2.2 感知机学习策略
找出线性可分的分离超平面,即确定感知机模型参数 w ⃗ \vec w w和b,定义(经验)损失函数并将损失函数最小化。
损失函数:误分类点到超平面S的总距离。
输入空间
R
n
\mathbf{R}^n
Rn中任一点
x
0
x_0
x0到超平面S的距离:
1
∣
∣
w
∣
∣
∣
w
⃗
⋅
x
⃗
+
b
∣
\frac{1}{||w||}|\vec w \cdot \vec x+b|
∣∣w∣∣1∣w⋅x+b∣。则对于误分类点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi),到超平面S的距离为
−
1
∣
∣
w
∣
∣
y
i
(
w
⃗
⋅
x
⃗
i
+
b
)
- \frac{1}{||w||}y_i(\vec w \cdot \vec x_i+b)
−∣∣w∣∣1yi(w⋅xi+b)。对所有误分类点到超平面S的距离求和,不考虑
1
∣
∣
w
∣
∣
\frac{1}{||w||}
∣∣w∣∣1,即可得到感知机的损失函数。
L
(
w
⃗
,
b
)
=
−
∑
x
i
∈
M
y
i
(
w
⃗
⋅
x
⃗
i
+
b
)
L(\vec w,b)=- \sum_{x_i \in M}y_i(\vec w \cdot \vec x_i +b)
L(w,b)=−xi∈M∑yi(w⋅xi+b)
其中M为误分类点的集合。
3 感知机学习算法
求解损失函数的最优化问题:随机梯度下降法(stochastic gradient descent)。
3.1 原始形式
-
选取初值 w 0 , b 0 w_0,b_0 w0,b0。
-
在训练机中选取数据 ( x i , y i ) (x_i,y_i) (xi,yi),作为误分类点。
-
如果 y i ( w ⃗ ⋅ x ⃗ i + b ) ≤ 0 y_i(\vec w \cdot \vec x_i+b)\leq 0 yi(w⋅xi+b)≤0
w ← w + η y i x i b ← b + η y i w \gets w + \eta y_ix_i \\ b \gets b+ \eta y_i w←w+ηyixib←b+ηyi -
转至2,直至训练集中没有误分类点。
3.2 算法的收敛性
对于线性可分数据集感知机学习算法原始形式收敛,即经过有限次迭代可以得到一个将训练数据集完全正确划分的分离超平面及感知机模型。Novikoff定理。
误分类次数k满足不等式:
k
≤
(
R
γ
)
2
,
R
=
max
1
≤
i
≤
N
∣
∣
x
i
∣
∣
,
γ
=
min
i
{
y
i
(
w
⃗
o
p
t
⋅
x
⃗
i
+
b
o
p
t
}
k \leq (\frac{R}{\gamma})^2,R = \max_{1 \leq i \leq N}||x_i||,\gamma = \min_{i}\{y_i(\vec w_{opt} \cdot \vec x_i+b_{opt}\}
k≤(γR)2,R=1≤i≤Nmax∣∣xi∣∣,γ=imin{yi(wopt⋅xi+bopt}
3.3 对偶形式
基本想法:将 w ⃗ \vec w w和b表示为实例 x ⃗ i \vec x_i xi和标记yi的线性组合的形式,通过求解其系数而求得w和b。
对于误分类点
(
x
⃗
i
,
y
i
)
(\vec x_i,y_i)
(xi,yi),通过3.1中逐步修改w,b,假设修改了ni次,
α
i
=
n
i
η
\alpha_i=n_i\eta
αi=niη,则
w
=
∑
i
=
1
N
α
i
x
i
y
i
b
=
∑
i
+
1
N
α
i
y
i
w = \sum_{i=1}^{N}\alpha_ix_iy_i \\ b = \sum_{i+1}^{N}\alpha_iy_i
w=i=1∑Nαixiyib=i+1∑Nαiyi
考虑
n
i
n_i
ni的含义:
n
i
n_i
ni表示
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)由于误分类而进行更新的次数。更新次数越多,意味着它离超平面越近。
则原始形式第3步的判断条件,需要关注 n i n_i ni。即若不符合条件,则更新次数加1。
对偶形式的意义在于,训练实例仅以内积的形式出现。可以预先将训练机中实例间的内积计算出来并以矩阵的形式存储,即Gram矩阵(任意两个向量的内积组成的矩阵)。
4 Python实现
import numpy as np
def sign (x):
if x >= 0:
return 1
else:
return -1
def training ():
positive_sample = [[3, 3, 1], [4, 6, 1], [4, 5, 1]]
negative_sample = [[1, 2, -1], [-1, 2, -1], [3, 5, -1]]
samples = positive_sample + negative_sample
w = np.array([0, 0])
b = 0
eta = 0.7
iterator_time = 1000000
sum = 0
for i in range(iterator_time):
sum += 1
index = np.random.randint(0, len(samples) - 1)
x = np.array(samples[index][:-1])
y = samples[index][-1]
if y * (np.dot(x, w) + b) <= 0:
w = w + eta * y * x
b = b + eta * y
print("Weight:" + str(w) + "------" + "Bias:" + str(b))
print(sum)
print("--------Result--------")
print(w)
print(b)
return [w, b]
def test (x):
arguments = training()
w = np.array(arguments[0])
b = arguments[1]
x_data = np.array(x)
return sign(np.dot(x_data, w) + b)
if __name__ == '__main__':
print("Test", test([2, 5]))