Dbscan clustering with distance matrix

I need to cluster “objects” that are not points in space, but I can calculate a distance between them. The documentation says:

There are two implementations of DBSCAN algorithm in this package (both provided by dbscan function):
Distance (adjacency) matrix-based. It requires O(N2)O(N2) memory to run. Boundary points cannot be shared between the clusters.

I wrote a small script to test this, but it does not work. The clustering package only seems to accept points in a space, not a precomputed distance matrix. Is it possible to cluster with a distance matrix?

using Clustering
points = [1.0, 2.0, 3.0, 4.0, 7.0, 8.0, 9.0, 10.0]
s = size(points)[1]
dists = zeros(s,s)
for k in 1:s
    for l in k+1:s
        d = sqrt((points[k] - points[l])^2)
        dists[k,l] = d
        dists[l,k] = d
r = 2.0
size, core, boundary = dbscan(dists, r, min_cluster_size = 3)
function dbscan(D::AbstractMatrix{T}, eps::Real, minpts::Int) where T<:Real 

Try supplying the third integer argument so that dispatch works correctly.

Thanks for replying. The error message changed; I now get a Julia 1.7.0. error. The code I used is:
size, core, boundary = dbscan(dists, r, 3)
The error (that I do not understand):

Exception has occurred: MethodError
MethodError: no method matching iterate(::DbscanResult)
Closest candidates are:
  iterate(!Matched::Union{LinRange, StepRangeLen}) at /usr/local/julia-1.7.0/share/julia/base/range.jl:826
  iterate(!Matched::Union{LinRange, StepRangeLen}, !Matched::Integer) at /usr/local/julia-1.7.0/share/julia/base/range.jl:826
  iterate(!Matched::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at /usr/local/julia-1.7.0/share/julia/base/dict.jl:695

You could try (;seeds, assignments, counts) = dbscan(dists, r,3) with julia 1.7
This version of dbscan returns a DbscanResult while the other implementation return a DbscanCluster. These do not behave the same…

Thank you. The error message changed again, and has become minimal:

Exception has occurred: ErrorException
type DbscanResult has no field size

 [1] top-level scope
   @ ~/juliatest/dbscantest.jl:13

I hope one more suggestion provides working code

The 1.7 syntax (;seeds, assignments, counts) = dbscan(dists, r,3) is equivalent to

rst = dbscan(dists,r,3)
seeds = rst.seeds
assignments = rst.assignments
counts = rst.counts

It only works to expose fields of a structure by their names. Therefore (;size, core,boundary)= dbscan(dists, r,3) fails because there are no such fields in a DbscanResult

Thanks! :smiley: