Commit 12962ecc by Corey Koval

Testing AutoEps

parent a920ae08
......@@ -37,6 +37,7 @@ from multiprocessing import Process, Queue
from bottle import route, run, request, get, post, put, response, redirect, template, static_file
from bottle.ext.websocket import GeventWebSocketServer, websocket
DBSCAN_Q = Queue()
DBSCAN_WAIT_Q = Queue()
DATABASE_EDIT_Q = Queue()
......@@ -227,6 +228,32 @@ def do_dbscan(X, epsilon, minsamp):
if not DBSCAN_WAIT_Q.empty():
DBSCAN_WAIT_Q.get()
####################################
# Autocalculate the best eps value.
####################################
def autoeps_calc(X):
X = X[:min(2000, len(X)):2]
min_distances = []
for x in X:
distances = []
for y in X:
distance = math.sqrt(sum([(a - b) ** 2 for a, b in zip(x, y)]))
if distance > 0:
distances.append(distance)
min_distances.extend(np.sort(distances)[0:3].tolist())
sorted_distances = np.sort(min_distances).tolist()
try:
for x1, y1 in enumerate(sorted_distances):
x2 = x1 + 1
y2 = sorted_distances[x2]
m = (y2 - y1) / (x2 - x1)
if m > 0.005:
# print(f"Slope: {round(m, 3)}, eps: {y1}")
return y1
except IndexError:
return 0
###############################################
# Computes DBSCAN Alorithm is applicable,
# finds the mean of a cluster of intersections.
......@@ -254,6 +281,9 @@ def process_data(database_name, epsilon, min_samp):
if epsilon > 0:
X = StandardScaler().fit_transform(intersect_array[:,0:2])
n_points = len(X)
autoeps = autoeps_calc(X)
min_samp = max(3, round(0.05 * n_points, 0))
print(f"min_samp: {min_samp}, eps: {autoeps}")
size_x = sys.getsizeof(X)/1024
print(f"The dataset is {size_x} kilobytes")
print(f"Computing Clusters from {n_points} intersections.")
......@@ -261,7 +291,8 @@ def process_data(database_name, epsilon, min_samp):
print("Waiting for my turn...")
time.sleep(1)
starttime = time.time()
db = Process(target=do_dbscan,args=(X,epsilon,min_samp))
db = Process(target=do_dbscan,args=(X,autoeps,min_samp))
# db = Process(target=do_dbscan,args=(X,epsilon,min_samp))
db.daemon = True
db.start()
try:
......
......@@ -247,13 +247,21 @@
const epsslider = document.getElementById("epsilonRange");
const minpointslider = document.getElementById("minpointRange");
const intersect_en = document.getElementById("intersect_en");
const clustering_en = document.getElementById("clustering_en");
if(minpointslider !== null) {
parameter += "minpts="+minpointslider.value+"&";
}
if(epsslider !== null) {
parameter += "eps="+epsslider.value+"&";
if (clustering_en !== null) {
if (clustering_en.checked) {
parameter += "eps=1&";
} else {
parameter += "eps=0&";
}
}
// if(epsslider !== null) {
// parameter += "eps="+epsslider.value+"&";
// }
if (intersect_en !== null) {
if (intersect_en.checked) {
parameter += "plotpts=true"+"&";
......@@ -392,7 +400,7 @@
</span>
<span class="slidevalue" id="confidence"></span>
</div>
<div class="tooltip">
<!-- <div class="tooltip">
<span class="tooltiptext">Epsilon:<br>
Maximum distance between neighboring points in a cluster. Set to 0 to disable clustering.<br>
Disabling clustering will plot all intersections and may cause longer load times.</span>
......@@ -407,6 +415,17 @@
<input name="minpointValue" type="range" min="0" max="300" step="5" value="{{minpoints}}" class="slider" id="minpointRange">
</span>
<span class="slidevalue" id="minpoints"></span>
</div> -->
<div style="width: 600px">
<span class="tooltip">
<span class="slidetitle"><h4>Clustering:</h4></span>
<span class="slidespan" style="text-align:left; width: 100px;margin: 5px;">
<label class="switch">
<input id="clustering_en" name="clustering_en" {{"checked" if epsilon > 0 else ""}} type="checkbox" onchange="updateParams()">
<span class="switchslider round"></span>
</label></span>
<span class="tooltiptext">Turns clustering on or off. Clustering On will draw ellipses.</span>
</span>
</div>
<div style="width: 600px">
<span class="tooltip">
......@@ -433,25 +452,26 @@
var confoutput = document.getElementById("confidence");
confoutput.innerHTML = confslider.value;
var epsslider = document.getElementById("epsilonRange");
var epsoutput = document.getElementById("epsilon");
epsoutput.innerHTML = epsslider.value;
// var epsslider = document.getElementById("epsilonRange");
// var epsoutput = document.getElementById("epsilon");
// epsoutput.innerHTML = epsslider.value;
var minpointslider = document.getElementById("minpointRange");
var minpointoutput = document.getElementById("minpoints");
minpointoutput.innerHTML = minpointslider.value;
// var minpointslider = document.getElementById("minpointRange");
// var minpointoutput = document.getElementById("minpoints");
// minpointoutput.innerHTML = minpointslider.value;
var rx_enable = document.getElementById("rx_en");
var intersect_en = document.getElementById("intersect_en");
// var clustering_en = document.getElementById("clustering_en");
// Update the current slider value (each time you drag the slider handle)
epsslider.oninput = function() {
epsoutput.innerHTML = this.value;
}
epsslider.onpointerup = function() {
updateParams("");
}
// epsslider.oninput = function() {
// epsoutput.innerHTML = this.value;
// }
// epsslider.onpointerup = function() {
// updateParams("");
// }
powerslider.oninput = function() {
poweroutput.innerHTML = this.value;
}
......@@ -464,12 +484,12 @@
confslider.onpointerup = function() {
updateParams("minconf="+this.value);
}
minpointslider.oninput = function() {
minpointoutput.innerHTML = this.value;
}
minpointslider.onpointerup = function() {
updateParams("");
}
// minpointslider.oninput = function() {
// minpointoutput.innerHTML = this.value;
// }
// minpointslider.onpointerup = function() {
// updateParams("");
// }
rx_enable.onchange = function() {
if (rx_enable.checked) {
......@@ -481,11 +501,6 @@
intersect_en.onchange = function() {
updateParams("");
// if (intersect_en.checked) {
// updateParams("plotpts=true");
// } else {
// updateParams("plotpts=false");
// }
}
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment