理解:感知机是分类模型,其单个特征向量最终训练结果是{+1,-1}。(这里不用输入空间,输出空间等术语).
函数:y=sign(wx+b)
参数解析:w和b是感知机的模型参数(不了解不要紧,往下看),w是权值(权值向量,x是个特征向量),b是偏置。sign(x)是一个函数,当x>=0时为+1,否则为-1。
几何解释:线性方程wx+b=0对应于空间中的一个超平面S,其中w是法向量,b是截距。这个超平面将空间划分为两部分,分别是正负两类。
咱们建立模型的时候就是求w和b。
x0到S的距离:y0=|wx0+b|/||w|| 这里||w||是w的L2范数
L0范数是指向量中非0的元素的个数。(L0范数很难优化求解)
L1范数是指向量中各个元素绝对值之和
L2范数是指向量各元素的平方和然后求平方根
L1范数可以进行特征选择,即让特征的系数变为0.
L2范数可以防止过拟合,提升模型的泛化能力,有助于处理 condition number不好下的矩阵(数据变化很小矩阵求解后结果变化很大)
(核心:L2对大数,对outlier离群点更敏感!)
下降速度:最小化权值参数L1比L2变化的快
模型空间的限制:L1会产生稀疏 L2不会。
L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0。 ———————————————— 版权声明:本文为CSDN博主「rocling」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/rocling/art…
那么我们很容易的就知道了,损失函数等于所有分类错误的点的y0之和。 损失函数: ==L(w,b)=∑|wx0+b|/||w||=-∑y0|wx0+b|/||w||(此时y0<0)==
那么大家说,咱们做这个感知机算法,是不是损失函数越小越好? 答案是肯定的,那么咱们就需要得到,min L(w,b)
怎么找呢? 用梯度下降法。
“梯度下降算法的解释:梯度下降算法最速下降法又称为梯度法,它是解析法中最古老的一种,其他解析方法或是它的变形,或是受它的启发而得到的,因此它是最优化方法的基础。作为一种基本的算法,他在最优化方法中占有重要地位。”
咱们把所有的y0,x0看称矩阵,Y,X.那么这个损失函数可以看称 L(w,b)=-Y(wX+b) 咱们要求的是w和b(X,Y已知),分开求,咱们要求的是L(w,b)的最小值,所以把。所以对w和b分别求导。 dL/dw=-YX dL/db=-Y
然后我们每算一次w和b的梯度(斜率或者是导数)就对w,b更新: w->w+αxiyi b->b+αyi α步长,也就是学习率(梯度下降每次的变化程度),(xi,yi)是随机的误分类点。我们期望损失函数一直减小,直到我们满意。
算法的收敛性:经过有限次迭代可以得到一个完全正确划分数据集的超平面(感知机模型)。为了方便推导我们将偏置b并入权重w,记作w^^=(w^T^,b)^T^
同样也将输入的向量扩充,加进常数1,记作x^^=(x^T^,1)^T^。
此时x^^w^^=wx+b
Novikoff定理:
有兴趣就记一下,不会的话我可以给解释的。(笔写拍照)
感知机学习算法的对偶形式:将w,b表示为xi和yi的线性组合形式,通过求其系数而求w和b,不失一般性,对误分类点(xi,yi)通过: w+αxiyi->w b+αyi->b 来逐步修改w,b,设修改n次,w,b的增量为βiyixi和βiyi,βi=αini 那么最后的w,b为(第一次w0=b0=0) w=∑βiyixi b=∑βiyi 那么Y=sign(∑βiyixiX+b)
于是出现算法:
为了方便我们可以把Gram矩阵先求出来:
G=[xi*X]
其实看不懂没关系,看下面这个你就懂了。
代码:(建议自己跟着写写)
原始形式的感知机:
import random
import numpy as np
import matplotlib.pyplot as plt
def sign(x):
if x>0:
return 1
else:
return 0
def train(train_num,train_datas,lr):
w=[0,0]
b=0
#第一轮w和b都设置成0
for i in range(train_num):
x=random.choice(train_datas)
#随机选择一个
x1,x2,y=x
#拿出数据
if(y*(w[0]*x1+w[1]*x2+b)<=0):
#if(y*sign((w[0]*x1+w[1]*x2+b))<=0):
#进入条件
w[0]+=x1*y*lr
w[1]+=x2*y*lr
b+=lr*y
return b,w
def plot_points(train_datas,w,b):
plt.figure()
#创建自定义图像
x1 = np.linspace(0, 8, 100)
#numpy.linspace(start,end,num)
#在start和end之间生成均匀的num个数据
x2 = (-b-w[0]*x1)/w[1]
#通过咱们的公式x1w1+x2w2+b=0求分界线
plt.plot(x1, x2, color='r', label='y1 data')
#画直线
datas_len=len(train_datas)
#数据个数
for i in range(datas_len):
if(train_datas[i][-1]==1):
#-1是拿第1个数据里的最后一个数据
plt.scatter(train_datas[i][0],train_datas[i][1],s=50)
#画点
else:
plt.scatter(train_datas[i][0],train_datas[i][1],marker='x',s=50)
plt.show()
if __name__=='__main__':
train_data1 = [[1, 3, 1], [2, 2, 1], [3, 8, 1], [2, 6, 1]] # 正面
train_data2 = [[2, 1, -1], [4, 1, -1], [6, 2, -1], [7, 3, -1]] #反面
train_datas = train_data1 + train_data2 #整体数据集
b,w=train(train_num=500,train_datas=train_datas,lr=0.1)
#train_num是训练次数,lr是步数。
plot_points(train_datas,w,b)
#画图,以后慢慢讲
对偶形式的感知机:
import random
import numpy as np
import matplotlib.pyplot as plt
def train(train_num,train_datas,lr):
w=0.0
#下面求w会需要float64类型的变量
b=0
#初始化
data_len=len(train_datas)
#求数据个数
alpha = [0 for i in range(data_len)]
#创建和数据个数数量元素的alpha矩阵
train_array = np.array(train_datas)
gram = np.matmul(train_array[:,0:-1] , train_array[:,0:-1].T)
#求gram看我那张图
for index in range(train_num):
value=0
i = random.randint(0,data_len-1)
#生成一个随机数范围为[0,data_len-1]
yi=train_array[i,-1]
for j in range(data_len):
value+=alpha[j]*train_array[j,-1]*gram[i,j]
value+=b
value=yi*value
#以上就是误分条件的左边
if(value<=0):
alpha[i]=alpha[i]+lr
for i in range(data_len):
w+=alpha[i]*train_array[i,0:-1]*train_array[i,-1]
b+=alpha[i]*train_array[i,-1]
return w,b,alpha,gram
def draw(train_datas,w,b):
plt.figure()
x1 = np.linspace(0, 8, 100)
x2 = (-b-w[0]*x1)/w[1]
#根据式子反推
plt.plot(x1, x2, color='r', label='y1 data')
datas_len=len(train_datas)
for i in range(datas_len):
if(train_datas[i][-1]==1):
plt.scatter(train_datas[i][0],train_datas[i][1],s=50)
else:
plt.scatter(train_datas[i][0],train_datas[i][1],marker='x',s=50)
plt.show()
if __name__=='__main__':
train_data1 = [[1, 3, 1], [2, 2, 1], [3, 8, 1], [2, 6, 1]] #正例
train_data2 = [[2, 1, -1], [4, 1, -1], [6, 2, -1], [7, 3, -1]] #反例
train_datas = train_data1 + train_data2
w,b,alpha,gram=train(train_num=500,train_datas=train_datas,lr=0.1)
draw(train_datas,w,b)
需要Novikoff求导的话说一下昂,我感觉这些定理,死记硬背应该行。