-
Notifications
You must be signed in to change notification settings - Fork 0
/
force.py
105 lines (90 loc) · 3.1 KB
/
force.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
"""
Force
Force multidimensional projection technique.
http://www.lcad.icmc.usp.br/%7Enonato/pubs/TejadaEtAl.pdf
"""
from __future__ import print_function
from projection import projection
try:
import numpy as np
import scipy.spatial.distance as dist
except ImportError as msg:
error = ", please install the following packages:\n"
error += " NumPy (http://www.numpy.org)\n"
error += " SciPy (http://www.scipy.org)"
raise ImportError(str(msg) + error)
class Force(projection.Projection):
"""
Force projection.
"""
def __init__(self, data, data_class, dtype="data", delta_frac=8,
niter=50, tol=1.0e-6):
"""
Class initialization.
"""
projection.Projection.__init__(self, data, data_class, 2)
self.dtype = dtype
self.delta_frac = delta_frac
self.niter = niter
self.tol = tol
def project(self):
"""
Project method.
Projection itself.
"""
assert type(self.data) is np.ndarray, \
"*** ERROR (Force): project input must be of numpy.ndarray \
type."
# number of instances, dimension of the data
ninst = self.data_ninstances
# random initialization
Y = np.random.random((ninst, self.projection_dim))
# computes distance in R^n
if self.dtype == "data":
distRn = dist.squareform(dist.pdist(self.data))
elif self.dtype == "dmat":
distRn = self.data
else:
print("*** ERROR (Force): Undefined data type.")
assert type(distRn) is np.ndarray and distRn.shape == (ninst, ninst), \
"*** ERROR (Force): project input must be numpy.ndarray \
type."
idx = np.random.permutation(ninst)
for k in range(self.niter):
# for each x'
for i in range(ninst):
inst1 = idx[i]
# for each q' != x'
for j in range(ninst):
inst2 = idx[j]
if inst1 != inst2:
# computes direction v
v = Y[inst2] - Y[inst1]
distR2 = np.hypot(v[0], v[1])
if distR2 < self.tol:
distR2 = self.tol
delta = (distRn[inst1][inst2] - distR2)/self.delta_frac
v /= distR2
# move q' = Y[j] in the direction of v by a fraction
# of delta
Y[inst2] += delta * v
self.projection = Y
def run():
import time
import sys
print("Loading data set... ", end="")
sys.stdout.flush()
data_file = np.loadtxt("iris.data")
print("Done.")
n, dim = data_file.shape
data = data_file[:, range(dim - 1)]
data_class = data_file[:, dim - 1]
start_time = time.time()
print("Projecting... ", end="")
sys.stdout.flush()
f = Force(data, data_class)
f.project()
print("Done. (" + str(time.time() - start_time) + "s)")
f.plot()
if __name__ == "__main__":
run()