-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsupportvectormachine.py
117 lines (96 loc) · 4.12 KB
/
supportvectormachine.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np
style.use('ggplot')
class Support_Vector_Machine:
def __init__(self, visualization = True):
self.visualization = visualization
self.colors = {1:'r', -1:'b'}
if self.visualization:
self.fig = plt.figure()
self.ax = self.fig.add_subplot(1,1,1)
#training
def fit(self, data, b_range_multiple = 5):
self.data = data
self.b_range_multiple = b_range_multiple
#{|w|: [w,b]}
opt_dict = {}
transform=[[1,1],
[-1,1],
[-1,-1],
[1,-1]]
all_data = []
for yi in self.data:
for featureset in self.data[yi]:
for feature in featureset:
all_data.append(feature)
self.max_feature_value = max(all_data)
self.min_feature_value = min(all_data)
all_data = None
step_sizes = [self.max_feature_value * 0.1,
self.max_feature_value * 0.01,
self.max_feature_value * 0.001]
b_multiple = 5
latest_optimum = self.max_feature_value * 10
for step in step_sizes:
w = np.array([latest_optimum, latest_optimum])
optimized = False
while not optimized:
for b in np.arange(-1 * (self.max_feature_value * b_range_multiple),
self.max_feature_value * b_range_multiple,
step * b_multiple):
for transformation in transform:
w_t = w * transformation
found_option = True
#yi*(xi.w + b) >= 1
for i in self.data:
for xi in self.data[i]:
yi = i
if not yi * (np.dot(w_t, xi) + b) >= 1:
found_option = False
if found_option:
opt_dict[np.linalg.norm(w_t)] = [w_t, b]
if w[0] < 0:
optimized = True
#print('Optimized a step')
else:
w = w - step
norms = sorted([n for n in opt_dict])
#|w| : [w, b]
opt_choice = opt_dict[norms[0]]
self.w = opt_choice[0]
self.b = opt_choice[1]
latest_optimum = opt_choice[0][0] + step * 2
def predict(self, features):
#sign(x.w + b)
classification = np.sign(np.dot(np.array(features), self.w) + self.b)
if classification != 0 and self.visualization:
self.ax.scatter(features[0], features[1], s = 200, marker = '*', c = self.colors[classification])
return classification
def visualize(self):
[[self.ax.scatter(x[0], x[1], s = 100, color = self.colors[i]) for x in self.data[i]] for i in self.data]
#hyperplane = v = x.w + b
#psv = 1
#nsv = -1
#dec = 0
def hyperplane(x, w, b, v):
return (-w[0] * x - b + v) / w[1]
datarange = (self.min_feature_value * 0.9, self.max_feature_value * 1.1)
hyp_x_min = datarange[0]
hyp_x_max = datarange[1]
#w.x + b = 1
#positive support vector hyperplane
psv1 = hyperplane(hyp_x_min, self.w, self.b, 1)
psv2 = hyperplane(hyp_x_max, self.w, self.b, 1)
self.ax.plot([hyp_x_min, hyp_x_max],[psv1, psv2], 'k')
#w.x + b = -1
#negative support vector hyperplane
nsv1 = hyperplane(hyp_x_min, self.w, self.b, -1)
nsv2 = hyperplane(hyp_x_max, self.w, self.b, -1)
self.ax.plot([hyp_x_min, hyp_x_max],[nsv1, nsv2], 'k')
#w.x + b = 0
#decision bountry
db1 = hyperplane(hyp_x_min, self.w, self.b, 0)
db2 = hyperplane(hyp_x_max, self.w, self.b, 0)
self.ax.plot([hyp_x_min, hyp_x_max],[db1, db2], 'y--')
plt.show()