1 基本概念
1.1 向量点乘
向量的点乘,也叫向量的内积、数量积,对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量。
向量
向量
则a,b点乘
点乘的几何意义是可以用来表征或计算两个向量之间的夹角,以及在b向量在a向量方向上的投影
1.2 点到直线距离公式
直线公式,直线外一点,则点到直线的距离公式为:
1.3 超平面
而d维空间中的超平面由下面的方程确定:,其中,w与x都是d维列向量为平面上的点, 为平面的法向量。b是一个实数, 决定平面与原点之间的距离(其他文章说是远点到平面的距离,其实是不对的).
平面外一点到平面的距离,是点到直线距离的延伸,
原点为(0,0,0...),所以原点到平面距离
1.4 感知机
感知机是二分类的的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1二值。
其中w和b为感知机的模型参数,w是权值向量,b叫做偏置,叫是w和x的的內积,sign为符号函数,当右边表达式值大于0时,函数值为1,当右边表达式小于0时,函数值为-1.
2 感知机的损失函数
2.1 误分类点到超平面总距离和损失函数
误分类点到平面的距离总和为:M为误分类点的集合,
对于误分类的数据来说,, 因为时,,时,,所以
忽略,则损失函数为(感知机中的损失函数中的分母为什么可以不考虑)
2.2 梯度下降法优化
对于,的梯度如下:
极小化的过程不是一次使M中的所有误分类点的梯度下降,而是随机选取一个误分类点使其梯度下降。
3 感知机代码实现(源)
import random
import numpy as np
import matplotlib.pyplot as plt
import time
class percePtron:
# 初始化w向量和截距b,注意初始化为浮点类型
def __init__(self):
self.weight = [0.0, 0.0]
self.bias = 0.0
def draw(self, x1, x2, y1, y2):
plt.scatter(x1, y1, label="y = 1")
plt.scatter(x2, y2, label="y = -1")
plt.legend()
plt.xlabel('X1')
plt.ylabel('X2')
label_x = np.linspace(0, 4, 20)
# print(-(self.bias + self.weight[0] * label_x) / self.weight[1])
plt.plot(label_x, -(self.bias + self.weight[0] * label_x) / self.weight[1])
plt.show()
# learning_rate=0.1表示为步长为0.1,step表示为训练次数,data为样本集
def train(self, data, learning_rate=0.01, step=1000):
self.weight = np.array(self.weight)
for i in range(step):
randomindex = random.randint(0, len(data) - 1)
#随机选取样本点
randomData = data[randomindex]
# 如果y(wx + b) <= 0,则表明这个点为误分类点
if randomData[2] * (self.weight[0] * randomData[0] + self.weight[1] * randomData[1] + self.bias) <= 0:
# 此处为梯度下降算法更新w和b
self.weight[0] = self.weight[0] + randomData[2] * randomData[0] * learning_rate
self.weight[1] = self.weight[1] + randomData[2] * randomData[1] * learning_rate
self.bias = self.bias + randomData[2] * learning_rate
print("weight : ", self.weight)
print("bias : ", self.bias)
if __name__ == "__main__":
data = [[1, 4, 1], [0.5, 2, 1], [2, 2.3, 1], [1, 0.5, -1], [2, 1, -1],
[4, 1, -1], [3.5, 4, 1], [3, 2.2, -1], [4, 2.2, -1], [5, 2.2, -1], [6, 2.2, -1]]
x1 = []
y1 = []
x2 = []
y2 = []
for p in data:
if p[2] > 0:
x1.append(p[0])
y1.append(p[1])
else:
x2.append(p[0])
y2.append(p[1])
x1 = np.array(x1)
x2 = np.array(x2)
y1 = np.array(y1)
y2 = np.array(y2)
model = percePtron()
model.train(data)
model.draw(x1, x2, y1, y2)
参考:
1 《统计学方法》
2 https://blog.csdn.net/lilong117194/article/details/78209862
3 https://blog.csdn.net/red_stone1/article/details/80491895
4 https://blog.csdn.net/dcrmg/article/details/52416832
5 https://www.cnblogs.com/BlueBlueSea/p/10059529.html