笔者,即将大四了,面临秋招的挑战,笔者以后想从事数据分析的相关工作,暑假实习自己在一家小公司做数据分析的工作,但是所接触到的工作内容都是比较偏业务方向的,偏技术的比重并没有我想象中的那么高,因此我想抓紧时间复习一下,加上之前看过台湾林轩田教授的机器学习视频,因此现在想试着去实现一下李航统计学习方法上面设计到的机器学习算法。
正文
感知机
:
假设输入空间是χ⊆Rn,输出空间是γ=(+1,−1)。输入χ∈X表示实例的特征向量,对应于输入空间的点;输出y∈γ表示实例的类别。由输入空间到输出空间的如下函数:
f(x)=sign(wx+b)
称为感知机。其中,w和b为感知机模型的参数,sign是符号函数,即:
![]()
sign好像很简单,当x大于等于0,sign输出1,否则输出-1。那么往前递归一下,wx+b如果大于等于0,f(x)就等于1,反之f(x)等于-1。我们再回头看一下感知机的函数f(x),简而言之,就是我们要找到那条线,wx+b,能够完美的将我们的数据集划分出来。
得出结论:
如果一条直线能够不分错一个点,那就是一条好的直线
进一步来说:
如果我们把所有分错的点和直线的距离求和,让这段求和的举例最小(最好是0,这样就表示没有分错的点了),这条直线就是我们要找的。
感知机的学习策略
就是说,我们要找到一条直线,就算这条直线不能将数据集完美切分,那么也要使错误分类的点到这条线上的距离之后最小,因此我们就要求每个点到线上的距离。
其实,我们对误分的点可以这样理解,例如实际应该属于线的右侧,y>0,但实际上预测出来是在左侧(wx+b<0),那就是分错了,结果是负,这时候再加个符号,结果就是正了,再除以w的模长,就是单个误分类的点到超平面的举例。举例总和就是所有误分类的点相加。
感知机的原始形式
感知机的对偶形式
具体算法实现:
import numpy as np
def perceptron(dataSet,eta):
# 获取到训练集的数据
dataMat = dataSet[:, 0:2]
# 获取标签数据
labelMat = dataSet[:, -1]
# 获取训练数据集的shape
m,n=dataMat.shape
# 初始化权重为0,样本长度保持一致
w=np.zeros(n)
# 初始化步长为0
b=0
flag=True
while flag:
for i in range(m):
# 获取当前样本的向量,当前样本所对应的标签,以及判断是否是误分标签
# 如果是误分标签,就进行梯度下降,更新w和b
if np.any(labelMat[i] * (np.dot(w, dataMat[i]) + b) <= 0):
w = w + eta * labelMat[i] * dataMat[i].T
b = b + eta * labelMat[i]
print("weight, bias: ", end="")
print(w, end=" ")
print(b)
flag = True
break
else:
flag = False
return w,b
def perceptron_dual(dataSet,eta):
# 获取到训练集的数据
dataMat = dataSet[:, 0:2]
# 获取标签数据
labelMat = dataSet[:, -1].reshape((-1,1))
# 获取训练数据集的shape
m, n = dataMat.shape
w=np.zeros((m,1))
b=0
flag = True
while flag:
for i in range(m):
if (labelMat[i, 0] * (np.sum((w * labelMat * np.dot(dataMat, dataMat[i].T).reshape((m, 1)))) + b)) <= 0:
w[i] = w[i] + eta
b = b + eta * labelMat[i]
flag = True
break
else:
flag = False
w = np.dot(dataMat.T, w * labelMat)
return w, b
if __name__ == '__main__':
# 定义样本数据集,与课本P29上的例题数据一样
dataSet = np.array([[3, 3, 1], [4, 3, 1], [1, 1, -1]])
w, b = perceptron_dual(dataSet,1)
print(w,b)