import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from functools import partial
# first set up the figure, the axis, and the plot element we want to animate
__FIG = plt.figure()
__AX = plt.axes(xlim=(0, 2), ylim=(-2, 2))
__LINE, = __AX.plot([], [], 'g', lw = 2)
__LABEL = __AX.text([], [], '')
# initialization function: plot the background of each framedef__init(trains):
__LINE.set_data([], [])
x, y, x_, y_ = [], [], [], []
for p in trains:
if p[1] > 0:
x.append(p[0][0])
y.append(p[0][1])
else:
x_.append(p[0][0])
y_.append(p[0][1])
plt.plot(x, y, 'bo', x_, y_, 'rx')
plt.axis([-6, 6, -6, 6])
plt.grid(True)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Prceptron Algorithm(wendale.cn)')
return __LINE, __LABEL
# animation function. this is called sequentiallydef__animate(history, i):global __AX, __LINE, __LABEL
w = history[i][0]
b = history[i][1]
if w[1] == 0:
return __LINE, __LABEL
x1 = -7
y1 = -(b + w[0]*x1)/w[1]
x2 = 7
y2 = -(b + w[0]*x2)/w[1]
__LINE.set_data([x1, x2], [y1, y2])
x1 = 0
y1 = -(b + w[0] * x1) / w[1]
__LABEL.set_text(history[i])
__LABEL.set_position([x1, y1])
return __LINE, __LABEL
defshow(trains, history, save=False, name=''):# call the animator. blit=true means only re-draw the parts that have changed.
anim = animation.FuncAnimation(__FIG, partial(__animate, history), init_func=partial(__init, trains),
frames=len(history), interval=1000, repeat=True, blit=True)
plt.show()
if save:
anim.save(name, fps=2, writer='imagemagick')
if __name__ == '__main__':
trains = np.array([[(3, 3), 1], [(4, 3), 1], [(1, 1), -1]])
history = [[[1.0, 0.0, -0.0], 1], [[1.0, 0.0, -1.0], 0], [[1.0, 0.0, -2.0], -1], [[1.0, 0.0, -3.0], -2], [[2.0, 0.0, -3.0], -1], [[2.0, 0.0, -4.0], -2], [[2.0, 0.0, -5.0], -3]]
show(trains, history)
二、原始形式
import copy
import draw
HISTORY = []
TRAINS = [[(3, 3), 1], [(4, 3), 1], [(1, 1), -1]]
defupdate(w, b, item):for i in range(len(item[0])):
w[i] += item[1] * item[0][i]
b += item[1]
return w, b
defcal(item):
res = 0for i in range(len(item[0])):
res += item[0][i] * w[i]
res += b
res *= item[1]
return res
defiterComp(w, b, trains):global HISTORY
flag = Falsefor item in trains:
if cal(item) <= 0:
flag = True
(w, b) = update(w, b, item)
HISTORY.append([copy.copy(w), b])
ifnot flag:
print"RESULT:w:" + str(w) + "b:" + str(b)
return flag, w, b
if __name__ == "__main__":
w = [0, 0]
b = 0whileTrue:
(flag, w, b) = iterComp(w, b, TRAINS)
ifnot flag:
break
draw.show(TRAINS, HISTORY, True, 'perceptron.gif')
效果
三、对偶形式
__author__ = 'wendale'import numpy as np
import draw
def__cal_gram(trains):
gram = np.empty((len(trains), len(trains)), np.int)
for i in range(len(trains)):
for j in range(len(trains)):
gram[i][j] = np.dot(trains[i][0], trains[j][0])
return gram
def__check(trains, gram, alpha, b):
y = np.array(trains[:,1])
for i in range(len(trains)):
if (np.dot(alpha * y, gram[i]) + b) * y[i] <= 0:
returnFalse, i
returnTrue, -1deffind(trains):
gram = __cal_gram(trains)
alpha = np.zeros(len(trains))
b = 0
x = np.array(trains[:,0].tolist()).reshape(3,2)
y = np.array(trains[:,1])
history = []
whileTrue:
(flag, i) = __check(trains, gram, alpha, b)
if flag:
break#update
alpha[i] += 1
b += trains[i][1]
history.append([np.dot(alpha * y, x).tolist(), b])
return alpha, b, history
if __name__ == '__main__':
trains = np.array([[[3, 3], 1], [[4, 3], 1], [[1, 1], -1]])
(a, b, history) = find(trains)
draw.show(trains, history, True, 'duality_perceptron.gif')