感知机原理及代码实现小结

感知机是线性分类模型,其输入是一个实例特征向量,输出是该实例的类别,取+1和-1。而感知机是输入空间(特征空间)中将实例划分为正负两类的分离超平面,属于判别模型。感知机学习的目标就是求出将训练数据进行线性划分的分离超平面,导入基于误分类的损失函数,利用梯度下降法对损失函数极小化,求得感知机模型。有一点,要注意:使用感知机的前提是训练数据线性可分。

1 感知机的模型

感知机模型
假设训练数据集\(T=\left \{ \left ( x_{1},y_{1} \right ),\left ( x_{2},y_{2} \right ),\cdots ,\left ( x_{m},y_{m} \right )\right \}\),其中,每个样本有\(n\)个特征,输出二元类别\(\left \{ +1,-1 \right \}\),感知机的目的是在特征空间中找到一个超平面\(S\)\(\theta _{0}+\theta _{1}x_{1}+\cdots+\theta _{n}x_{n}=0\),将特征空间划分成两个部分,位于两部分的点分别被分为正类和负类。由于使用感知机的前提是数据线性可分,因此超平面\(S\)不是唯一的,感知机模型有多个解。令\(x_{0}=1\),超平面\(S\)表达式为:

\[\sum_{i=0}^{n}\theta _{i}x_{i}=0 \]

其向量表示为:\(\theta ^{T}\cdot x=0\),其中\(\theta\)\(x\)均为\((n+1)\times 1\)的列向量。
感知机模型的表达式:\(y=sign(\theta ^{T}\cdot x)\)
其中,

\[sign(x)=\left\{\begin{matrix} +1, x\geq 0 & \\ -1, x< 0& \end{matrix}\right.\]

感知机损失函数
输入空间中任一点\(x_{0}\)到超平面\(S\)的距离表达式为:$$\frac{|\theta ^{T}\cdot x^{(i)}|}{||\theta ||{2}}$$
对于误分类的数据\(\left ( x_{i},y_{i} \right )\),$$-y
(\theta ^{T}\cdot x)> 0$$
因为当\(\theta ^{T}\cdot x> 0\)时,\(y_{i}=-1\),而当\(\theta ^{T}\cdot x< 0\)时,\(y_{i}=+1\)。所以,误分类点\(x_{i}\)到超平面\(S\)的距离表达式为:$$-\frac{y_{i}(\theta ^{T}\cdot x^{(i)})}{||\theta ||{2}}$$
假设超平面\(S\)的误分类点集合为\(M\),所有误分类点到超平面\(S\)的总距离表达式为: $$-\frac{1}{||\theta||
{2}}\sum_{x_{i}\epsilon M}y_{i}(\theta ^{T}\cdot x^{(i)})$$
不考虑\(\frac{1}{||\theta||_{2}}\),则得到感知机损失函数表达式为:$$J(\theta )=-\sum_{x_{i}\epsilon M}y_{i}(\theta ^{T}\cdot x^{(i)})$$
由损失函数看出,损失函数是非负的,没有误分类点时,损失函数值为0,当误分类点越少,误分类点离超平面越近,损失函数值就越小。

2 感知机算法

感知机算法

输入: 线性可分数据集\(T=\left \{ (x_{1},y_{1}),(x_{2},y_{2}),\cdots ,(x_{m},y_{m}) \right \}\),每个样本是\(n\)维特征,\(y_{i}\epsilon \left \{ -1,+1 \right \}\),学习率\(\alpha\)(\(0< \alpha \leq 1\));

输出: 感知机模型参数 $\theta $向量;

step1 初始化$\theta \(和\)\alpha$

step2 数据集中选择一个误分类点\((x_{i},y_{i})\),这里\(x_{i}\)\(n\)维向量,如果该点满足\(y_{i}(\theta ^{T}\cdot x_{i})\leq 0\)

step3 对感知机模型参数 $\theta $向量进行一次随机梯度下降迭代: \(\theta :=\theta +\alpha y_{i}x_{i}\)

step4 直到数据集中不存在误分类点,否则跳转至步骤2

3 感知机代码实现

from sklearn.datasets import make_classification
x,y = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_informative=1, n_clusters_per_class=1)


#训练数据和测试数据
x_data_train = x[:800,:]
x_data_test = x[800:,:]
y_data_train = y[:800]
y_data_test = y[800:]

#正例和反例
positive_x1 = [x[i,0] for i in range(1000) if y[i] == 1]
positive_x2 = [x[i,1] for i in range(1000) if y[i] == 1]
negetive_x1 = [x[i,0] for i in range(1000) if y[i] == 0]
negetive_x2 = [x[i,1] for i in range(1000) if y[i] == 0]

#定义一个感知机
from sklearn.linear_model import Perceptron
clf = Perceptron(fit_intercept=False, n_iter=30, shuffle=False)
clf.fit(x_data_train, y_data_train)
print(clf.coef_)
#输出
[[-0.33706658  3.30497893]]
print(clf.intercept_)
#输出
[ 0.]

acc = clf.score(x_data_test,y_data_test)
print(acc)  #0.985

#可视化感知机结果

import numpy as np
from matplotlib import pyplot as plt
#画出正例和反例的散点图
plt.scatter(positive_x1,positive_x2,c='red')
plt.scatter(negetive_x1,negetive_x2,c='blue')
#画出超平面(在本例中即是一条直线)
line_x = np.arange(-4,4)
line_y = line_x * (-clf.coef_[0][0] / clf.coef_[0][1]) - clf.intercept_
plt.plot(line_x,line_y)
plt.show()             

感知机小结

posted @ 2019-08-31 22:34  Christine_7  阅读(1573)  评论(0编辑  收藏  举报