您的位置:首页 > 编程语言 > Go语言

机器学习基石(2) - Perceptron Learning Algorithm

2017-08-18 21:39 435 查看

Notation

A: 机器学习算法

f: 未知的目标函数

D: 训练集合。(xn,yn)∈D 表示一个样本点,其中yn=f(xn)

H: 假设函数集合(hypothesis set)。h∈H表示一个假设函数

g: A从H中选出的最接近f的假设函数

An example

银行要不要向信用卡申请人发放信用卡:Yes|No?

已知信息:

银行提供了一堆历史数据,(xn,yn)∈D,n∈{1,2,3,...,N}, 其中xn是一个高维向量,表示用户的个人信息,诸如年龄、收入、贷款等等,yn∈{−1,+1},分别表示不发信用卡和发信用卡两种情形

未知信息:

1. 该用什么样的H呢?

2. 假设有了一个H,该怎么从中选呢?

一个简单的H: Perceptron(感知器)

Perceptron的假设函数为,

h(xn)=sign(wTxn−threshold)

结合发信用卡的例子,h(xn)实际上是把申请人的各项信息加权求和,然后和一个阈值做比较。如果大于阈值,则向此申请人发信用卡,否则不发。

另w←{−threshold,w}, xn←{1,xn},则h(xn)可以变换为,

h(xn)=sign(wTxn)

从几何的角度看,h对应的是空间里的一条直线或者一个超平面(w表示h的法向量),把数据分隔在两边。如下图所示,



从H选择g

PLA算法

如果存在g≈f ⇒ 在D上,理想情况下,对任意的xn,都有g(xn)=f(xn)=yn

反过来是否成立呢?课程在后面的章节中会再论述。

此处,可以暂且认为,反过来也是成立的。

所以,问题转化为,从H找到在D上表现最好的g。

难点:H集合无限大

方法:从任意h开始,慢慢修正它,直到达到最好的结果。因为h是由w确定的(Perceptron函数的定义),所以调整w即是在调整h。

什么时候调整?

当h(xn)≠yn时

错误发生时,如何调整?

如果 yn=1, h(xn)=−1,意味着w和xn的夹角过大 ⇒ w向xn靠近一些:w←w+xn

如果 yn=−1, h(xn)=1,意味着w和xn的夹角过小 ⇒ w向xn远离一些:w←w−xn

综上,w←w+ynxn

代码

demo (TODO)

# 待验证
import numpy as np

def sign(x, w):
if np.dot(x, w) >= 0:
return 1
else:
return -1

def PLA(X, Y):
"""
Perceptron Learning algorithm API
:param X: training data
:param Y: label data {-1, 1}
:return: best hypothesis function <g>
"""
num, d = np.shape(X)
w = np.zeros(d) # 初始化

while True:
halt = True
for n in range(num):
if sign(X
, w) != Y
: # 错误发生了,需要调整
halt = False
w = w + Y
* X
# 调整的办法
break
else:
continue
if halt:
break
return w


Guarantee of PLA

PLA面临的几个问题:

1. PLA算法一定会终止吗?

2. 如果能终止,在D以外,一定有g≈f吗?

3. 如果不能终止,怎么办?

终止条件

容易得出,PLA可以终止 ⇒D 线性可分。

那么,D 线性可分 ⇒ PLA可以终止,是不是一定正确?

证明:

1. D线性可分 ⇒∃wf表示的线(面)可以把D分开

2. 计算PLA每次调整w时,能否靠近wf(夹角越来越小),即wt⋅wf∥wt∥∥wf∥是不是随着每次调整在递增。

首先来看wt⋅wf。因为调整发生在分错的情况下,所以

wt⋅wf=wTfwt=wTf(wt−1+yn(t−1)xn(t−1))

=wTfwt−1+yn(t−1)wTfxn(t−1)

又因为,wf能分对所有点,所以对任意的xn,都有ynwTfxn≥0。所以,

wt⋅wf≥wTfwt−1+minynwTfxn

≥wTfwt−2+2minynwTfxn≥⋅⋅⋅≥wTfw0+TminynwTfxn

再来看∥wt∥∥wf∥,因为∥wt∥=wTtwt√,所以先计算wTtwt

wTtwt=(wt−1+yn(t−1)xn(t−1))T(wt−1+yn(t−1)xn(t−1))

=wTt−1wt−1+2yn(t−1)wTt−1xn(t−1)+xTn(t−1)xn(t−1)

≤wTt−1wt−1+xTn(t−1)xn(t−1)≤wTt−1wt−1+maxxTnxn

≤wTt−2wt−2+2maxxTnxn≤⋅⋅⋅≤wT0w0+TmaxxTnxn

综上,

wt⋅wf∥wt∥∥wf∥≥wTfw0+TminynwTfxn∥wf∥wT0w0+TmaxxTnxn√

因为PLA初始化w0=0, 所以

wt⋅wf∥wt∥∥wf∥≥TminynwTfxn∥wf∥TmaxxTnxn√

从这个不等式可以看出,不等式的右侧是关于T的单调递增函数。所以PLA在每次调整w时,的确是向着wf的方向进行的。意味着,PLA最终能选到wf,把D完美划分开。

结论:PLA可以终止 ⇔D 线性可分 (充分必要条件)

D线性不可分

如下图所示,在训练集上,数据可能有噪声,导致D上大部分数据可以被wf分正确,少部分会被分错。



在这种情况下,一个合理的做法是,选分错数据最少的那条线:

wg=argminw∑n=1N1(yn≠sign(wTxn))

使用贪心算法来求解wg,把PLA算法修改为,

import numpy as np

def sign(x, w):
if np.dot(x, w) >= 0:
return 1
else:
return -1

def misclassified(X, Y, w):
num = np.shape(X)[0]
count = 0
for n in range(num):
if sign(X
, w) != Y
:
count += 1
return count

def Pocket_PLA(X, Y, iteration):
num, d = np.shape(X)
w = np.zeros(d)
sample_index = np.arange(num)
err = d  # suppose all training samples are misclassified

for i in range(iteration):
np.random.shuffle(sample_index)
halt = True
for n in sample_index:
# randomly select the misclassified training sample
if sign(X
, w) != Y
:
new_w = w + Y
* X

new_err = misclassified(X, Y, new_w)
if new_err < err:
w = new_w
err = new_err
halt = False
break
if halt:
iteration = i
break

return w, iteration


总结

PLA可以终止 ⇔D 线性可分

PLA优点:实现简单、效率高、可扩展到任意维度

PLA缺点:太强的假设条件(D线性可分); 即使在线性可分的前提下,不确定算法什么时候会终止

课程作业

TODO
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  机器学习