笔记|统计学习方法:感知机模型

1
2
3
4
5
6
7
8
(由于我的markdown文件是使用VSC写的,在此顺便记录一下markdown语法)
Tips:需要在Git中使用 npm install hexo-math --save 命令来安装数学公式环境

VSC中预览:先按住ctrl+k,松开后按v
ctrl B 粗体
ctrl l 斜体
ctrl shift ] == #
ctrl m 标记数学公式环境**

感知机(perception)是一个二分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取+1与-1二值

1.感知机模型

假设输入空间(特征空间)是 ,输出空间是。输入 表示实例的特征向量,对应输出空间(特征空间)的点;输出 表示实例的类别,由输入空间到输出空间的如下函数 称为感知机。其中,和b为感知机模型参数, 叫作权值(weight)或权值向量(weight vector),叫作偏置(bias),表示和x的内积。sign是符号函数,即: 感知机是一种线性分类模型,属于判别模型。感知机的假设空间的定义是在特征空间中的所有线性分类模型或者线性分类器,即函数集合

2.感知机的几何解释

线性方程 对应特征空间中的一个超平面是超平面的法向量,b是超平面的截距,则这条线将超平面分离成正负两类。 感知机学习,由训练数据集 其中, ,,就得到了感知机模型,即求得模型参数,b。

3.感知机的学习策略

数据集的线性可分

对于给定的数据集 其中, ,

能将数据集的正负实例点完全正确地划分到超平面的两侧。可如此划分则称为线性可分数据集否则称为数据集不可分

4.损失函数

由点到平面距离公式可得,一个错误分类的点到超平面的距离为 对于分类错误的点,一定有 则所有错误分类的点到超平面的总距离 则感知机的损失函数为 所有样本都分类正确时,损失函数为0,错误越少,损失函数越小,分类错误样本离超平面距离越近,则损失函数越小。因此感知机的学习目标就是最小化该损失函数。

5.梯度下降法

通俗的讲话,梯度就是导数和偏导数,梯度下降法的思想是:梯度方向是目标函数值下降最快的方向,因此沿着梯度下降的方向优化能最快寻找到目标函数的极小值。 参数、b的更新可以表示为: 在感知机中采用随机梯度下降法,即每次随机选择一个分类错误的样本计算,进行和b的更新,即: 其过程直观理解为:当一个样本被当前超平面划分到分类错误一类时,利用此样本调整超平面的参数,使超平面向靠近该样本的方向移动,则该样本距离超平面的距离减小,从而降低损失函数,直到超平面移动至使该样本被正确划分为止。

6.例子

7.python代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import numpy as np;
import pandas as pd;
import matplotlib.pyplot as plt;


df=pd.read_excel("D:\pythondata\perceptrondata.xls");#读取原题数据
df=pd.DataFrame(df);
x=df.values[:,:-1];#x代表所有行的第一列到倒数第二列的数据,即分类实例的所有特征向量
y=df.values[:,-1];#y代表df的倒数第一列数据,即分类实例的所有类别
a=x.shape;
n=a[0];#n代表x特征向量的行数
m=a[1];#m代表x特征向量的列数
w=[];#创建空列表,w代表分离超平面中的法向量
for i in range(m):
w.append(0);#列表的长度与特征向量的特征个数相同
#若直接命令w[0]=0,w[1]=0时,会报错,直接按照索引向列表内添加东西时,因为空的列表不能直接指定其位置。
b=0;#b代表分离超平面的截距
k=1;#用来判别是否找到最优的超平面。假设值为1,即未找到
while (k==1):
k=0;
for i in range(n):
t=np.dot(w,x[i]);#用来计算w*x
if (y[i]*(t+b)<=0):
w=w+np.dot(y[i],x[i]);
b=b+y[i];
k=1;
print("分离超平面的法向量w={0},截距b={1}".format(w,b));
########可视化结果
#
def plot_and_scatter(df=None,w=0,b=0):
xmin=df.values[:,:-1].min();
xmax=df.values[:,:-1].max();
xdiff=(xmax-xmin)*0.5;
xx=np.linspace((xmin-xdiff),(xmax+xdiff),100);
yy=-b-w[1]*xx;
plt.figure();
plt.xlabel("X(1)");
plt.ylabel("X(2)");#设置坐标轴的文字标签
ax=plt.gca();# get current axis 获得坐标轴对象
ax.spines["right"].set_color("none");
ax.spines["top"].set_color("none"); # 将右边 上边的两条边颜色设置为空 其实就相当于抹掉这两条边
ax.xaxis.set_ticks_position("bottom");
ax.yaxis.set_ticks_position("left");
ax.spines["bottom"].set_position(("data",0));
ax.spines["left"].set_position(("data",0));#指定 data设置的bottom(也就是指定的x轴)绑定到y轴的0这个点上
plt.plot(xx,yy,"r");
color_list=["blue","green","black","pink","orange"];
y=df.values[:,-1];

a=set(y);
a=list(a);
y_num=len(a);
t=0;
for j in range(y_num):
tt=a[j];
y_index=[i for i,y in enumerate(y) if y==tt];
x_group1=df.values[y_index,0];
x_group2=df.values[y_index,1];
plt.scatter(x_group1,x_group2);
t=t+1;

plot_and_scatter(df,w,b);
plt.show();