I specify 'n' amount of points. Label them +1
or -1
. I store all this in a dictionary that looks like: {'point1' : [(0.565,-0.676), +1], ... }
. I am trying to find a line that separates them - i.e. points labeled +1 above the line, those -1 below the line. Can anyone help?
I'm trying to apply w = w + y(r)
as the "learning algorithm", w
is the weight vector y
is +1
or -1
, r
is the point
The code runs but the separating line is not precise - it doesn't separate correctly. Also, as I increase the number of points to separate, the line gets less efficient.
If you run the code, the green line is supposed to be the separating line. The closer it get to the slope of the blue line (the perfect line by definition), the better.
from matplotlib import pyplot as plt
import numpy as np
import random
n = 4
x_values = [round(random.uniform(-1,1),3) for _ in range(n)]
y_values = [round(random.uniform(-1,1),3) for _ in range(n)]
pts10 = zip(x_values, y_values)
label_dict = {}
x1, y1, x2, y2 = (round(random.uniform(-1,1),3) for _ in range(4))
b = [x1, y1]
d = [x2, y2]
slope, intercept = np.polyfit(b, d, 1)
fig, ax = plt.subplots(figsize=(8,8))
ax.scatter(*zip(*pts10), color = 'black')
ax.plot(b,d,'b-')
label_plus = '+'
label_minus = '--'
i = 1
for x,y in pts10:
if(y > (slope*x + intercept)):
ax.annotate(label_plus, xy=(x,y), xytext=(0, -10), textcoords='offset points', color = 'blue', ha='center', va='center')
label_dict['point{}'.format(i)] = [(x,y), "+1"]
else:
ax.annotate(label_minus, xy=(x,y), xytext=(0, -10), textcoords='offset points', color = 'red', ha='center', va='center')
label_dict['point{}'.format(i)] = [(x,y), "-1"]
i += 1
# this is the algorithm
def check(ww,rr):
while(np.dot(ww,rr) >= 0):
print "being refined 1"
ww = np.subtract(ww,rr)
return ww
def check_two(ww,rr):
while(np.dot(ww,rr) < 0):
print "being refined 2"
ww = np.add(ww,rr)
return ww
w = np.array([0,0])
ii = 1
for x,y in pts10:
r = np.array([x,y])
print w
if (np.dot(w,r) >= 0) != int(label_dict['point{}'.format(ii)][1]) < 0:
print "Point " + str(ii) + " should have been below the line"
w = np.subtract(w,r)
w = check(w,r)
elif (np.dot(w,r) < 0) != int(label_dict['point{}'.format(ii)][1]) >= 0:
print "Point " + str(ii) + " should have been above the line"
w = np.add(w,r)
w = check_two(w,r)
else:
print "Point " + str(ii) + " is in the correct position"
ii += 1
ax.plot(w,'g--')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_title('Labelling 10 points')
ax.set_xticks(np.arange(-1, 1.1, 0.2))
ax.set_yticks(np.arange(-1, 1.1, 0.2))
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.legend()