重读李航博士的《统计学方法》对感知机做个总结包括感知机原始形式和对偶对偶形式的原理和Python实现。
Python 实现
import numpy as np
steps = 1000
learning_rate = 1
X = np.array([[3,3],[4,3],[1,1]])
y = np.array([1,1,-1])
# "normal" 感知机原始形式; "dual"感知机对偶形式
class Perceptron():
def __init__(self, learning_rate,steps,model="normal"):
"""
:param model: "normal" and "dual"
"""
self.learning_rate = learning_rate
self.steps = steps
self.model = model
def fit(self, X,y):
"""
:param X: shape is (samples, feature size)
:param y: shape is (samples,)
:return: None
"""
if self.model == "normal":
W = np.zeros((X.shape[1]))
b = np.zeros((1))
for step in range(self.steps):
for i in range(X.shape[0]):
s = 0
# 判断是否是误分类点
ls = y[i] * (np.dot(X[i],W) + b)
if ls <= 0:
# print("第 %d 个样本分类错误" % i)
W = W + self.learning_rate* X[i] * y[i]
b = b + self.learning_rate* y[i]
print("W", W, "b", b)
s += 1
if s == 0:
self.W = W
self.b = b
print("全部分类正确")
break
elif self.model == "dual":
a = np.zeros((X.shape[0]))
b = np.zeros((1))
Gram = np.dot(X,X.T)
W = np.dot(a * y, X)
for step in range(self.steps):
for i in range(X.shape[0]):
s = 0
ls = y[i] * (np.dot(a * y, Gram[i]) + b)
if ls <= 0:
a[i] = a[i] + learning_rate
b = b + learning_rate * y[i]
W = np.dot(a * y, X)
print("W", W,"b",b)
s += 1
if s==0:
self.W = W
self.b = b
print("全部分类正确")
break
else:
print('model is "normal" or "dual"')
def predict(self, X):
result = np.dot(X,self.W.reshape(-1,1)) + self.b
return np.where(result >= 0, 1,-1)
def sampleLoss(self, X, y, W, b):
return np.sum(y * (np.dot(X, W.T) + b))
if __name__ == "__main__":
clf = Perceptron(learning_rate, steps,model="normal")
clf.fit(X,y)
print("####### predict ####### \n",clf.predict(X))
参考:
- 《统计学方法》李航
- 浅析感知机(二)--学习算法及python代码剖析
网友评论