forked from EricYizhenWang/robust_nn_icml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrobust_1nn.py
82 lines (73 loc) · 2.85 KB
/
robust_1nn.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
from __future__ import division
import numpy as np
from eps_separation import find_eps_separated_set
from sklearn.neighbors import NearestNeighbors, KNeighborsClassifier
class Robust_1NN:
def __init__(self, X, Y, Delta, delta, r):
self.r = r
self.X = X
self.Y = Y
self.Delta = Delta
self.delta = delta
n = X.shape[0]
self.n = n
self.k = min(int(3*np.log(n/delta)/(np.log(2)*(Delta**2))), n)
d = np.array([[np.linalg.norm(a-b) for a in X] for b in X])
self.d = d
def find_confident_label(self):
[X, Y, k, delta, n] = [self.X, self.Y,
self.k, self.delta,
self.n]
thres = 2*self.Delta
print thres, k
neigh = NearestNeighbors(k)
neigh.fit(X)
nn = neigh.kneighbors(X, k, return_distance=False)
Y_hat = np.array([[Y[j] for j in i] for i in nn])
Y_hat = np.sum(Y_hat, axis=1)/k
Y_hat = [0 if (abs(Y_hat[i])<thres) else np.sign(Y_hat[i])
for i in range(n)]
Y_hat = np.array(Y_hat)
self.Y_hat = Y_hat
return Y_hat
def find_red_points(self):
[X, Y, d, r, F] = [self.X, self.Y, self.d, self.r, self.Y_hat]
n = X.shape[0]
is_close = (d<r)
is_red = np.ones((n, 1))
for i in range(n):
for j in range(n):
if (is_close[i, j]) and (F[i]!=F[j]):
is_red[i]=0
if (F[i]!=Y[i]):
is_red[i]=0
red_pts = [np.array([X[i] for i in range(n) if is_red[i]]),
np.array([Y[i] for i in range(n) if is_red[i]])]
other_pts = [np.array([X[i] for i in range(n) if not is_red[i]]),
np.array([Y[i] for i in range(n) if not is_red[i]])]
[self.X_red, self.Y_red] = [red_pts[0], red_pts[1]]
[self.X_other, self.Y_other] = [other_pts[0], other_pts[1]]
return [red_pts, other_pts]
def find_robust_training_set(self):
self.find_confident_label()
self.find_red_points()
[X, Y, r] = [self.X_other, self.Y_other, self.r]
[X, Y] = find_eps_separated_set(X, r/2, Y)
if self.X_red.shape[0] > 0:
self.X_train = np.concatenate([X, self.X_red])
self.Y_train = np.concatenate([Y, self.Y_red])
else:
self.X_train = X
self.Y_train = Y
return self.X_train, self.Y_train
def fit(self, X=None, Y=None):
self.find_robust_training_set()
[X, Y] = [self.X_train, self.Y_train]
self.neigh = KNeighborsClassifier(n_neighbors=1)
self.neigh.fit(X, Y)
def predict(self, X):
self.neigh.predict(X)
def get_clf(self):
return self.neigh
def get_data(self):
return [self.X_train, self.Y_train]