% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dbscan.R, R/predict.R
\name{dbscan}
\alias{dbscan}
\alias{DBSCAN}
\alias{print.dbscan_fast}
\alias{is.corepoint}
\alias{predict.dbscan_fast}
\title{Density-based Spatial Clustering of Applications with Noise (DBSCAN)}
\usage{
dbscan(x, eps, minPts = 5, weights = NULL, borderPoints = TRUE, ...)

is.corepoint(x, eps, minPts = 5, ...)

\method{predict}{dbscan_fast}(object, newdata, data, ...)
}
\arguments{
\item{x}{a data matrix, a data.frame, a \link{dist} object or a \link{frNN} object with
fixed-radius nearest neighbors.}

\item{eps}{size (radius) of the epsilon neighborhood. Can be omitted if
\code{x} is a frNN object.}

\item{minPts}{number of minimum points required in the eps neighborhood for
core points (including the point itself).}

\item{weights}{numeric; weights for the data points. Only needed to perform
weighted clustering.}

\item{borderPoints}{logical; should border points be assigned to clusters.
The default is \code{TRUE} for regular DBSCAN. If \code{FALSE} then border
points are considered noise (see DBSCAN* in Campello et al, 2013).}

\item{...}{additional arguments are passed on to the fixed-radius nearest
neighbor search algorithm. See \code{\link[=frNN]{frNN()}} for details on how to
control the search strategy.}

\item{object}{clustering object.}

\item{newdata}{new data points for which the cluster membership should be
predicted.}

\item{data}{the data set used to create the clustering object.}
}
\value{
\code{dbscan()} returns an object of class \code{dbscan_fast} with the following components:

\item{eps }{ value of the \code{eps} parameter.}
\item{minPts }{ value of the \code{minPts} parameter.}
\item{cluster }{A integer vector with cluster assignments. Zero indicates noise points.}

\code{is.corepoint()} returns a logical vector indicating for each data point if it is a
core point.
}
\description{
Fast reimplementation of the DBSCAN (Density-based spatial clustering of
applications with noise) clustering algorithm using a kd-tree.
}
\details{
The
implementation is significantly faster and can work with larger data sets
than \code{\link[fpc:dbscan]{fpc::dbscan()}} in \pkg{fpc}. Use \code{dbscan::dbscan()} (with specifying the package) to
call this implementation when you also load package \pkg{fpc}.

\strong{The algorithm}

This implementation of DBSCAN follows the original
algorithm as described by Ester et al (1996). DBSCAN performs the following steps:
\enumerate{
\item Estimate the density
around each data point by counting the number of points in a user-specified
eps-neighborhood and applies a used-specified minPts thresholds to identify
core, border and noise points.
\item Core points are joined into
a cluster if they are density-reachable (i.e., there is a chain of core
points where one falls inside the eps-neighborhood of the next).
\item Border points are assigned to clusters. The algorithm needs parameters
\code{eps} (the radius of the epsilon neighborhood) and \code{minPts} (the
density threshold).
}

Border points are arbitrarily assigned to clusters in the original
algorithm. DBSCAN* (see Campello et al 2013) treats all border points as
noise points. This is implemented with \code{borderPoints = FALSE}.

\strong{Specifying the data}

If \code{x} is a matrix or a data.frame, then fast fixed-radius nearest
neighbor computation using a kd-tree is performed using Euclidean distance.
See \code{\link[=frNN]{frNN()}} for more information on the parameters related to
nearest neighbor search. \strong{Note} that only numerical values are allowed in \code{x}.

Any precomputed distance matrix (dist object) can be specified as \code{x}.
You may run into memory issues since distance matrices are large.

A precomputed frNN object can be supplied as \code{x}. In this case
\code{eps} does not need to be specified. This option us useful for large
data sets, where a sparse distance matrix is available. See
\code{\link[=frNN]{frNN()}} how to create frNN objects.

\strong{Setting parameters for DBSCAN}

The parameters \code{minPts} and \code{eps} depend on each other and
changing one typically requires changing the other one as well. The original
DBSCAN paper suggests to start by setting \code{minPts} to the
dimensionality of the data plus one or higher. \code{minPts} defines the
minimum density around a core point (i.e., the minimum density for non-noise
areas). Increase the parameter to suppress more noise in the data and
require more points to form a cluster. A suitable neighborhood size
parameter \code{eps} given a fixed value for \code{minPts} can be found
visually by inspecting the \code{\link[=kNNdistplot]{kNNdistplot()}} of the data using
\code{k = minPts - 1} (\code{minPts} includes the point itself, while the
k-nearest neighbors distance does not). The k-nearest neighbor distance plot
sorts all data points by their k-nearest neighbor distance. A sudden
increase of the kNN distance (a knee) indicates that the points to the right
are most likely outliers. Choose \code{eps} for DBSCAN where the knee is.

\strong{Predict cluster memberships}

\code{\link[=predict]{predict()}} can be used to predict cluster memberships for new data
points. A point is considered a member of a cluster if it is within the eps
neighborhood of a core point of the cluster. Points
which cannot be assigned to a cluster will be reported as
noise points (i.e., cluster ID 0).
\strong{Important note:} \code{predict()} currently can only use Euclidean distance to determine
the neighborhood of core points. If \code{dbscan()} was called using distances other than Euclidean,
then the neighborhood calculation will not be correct and only approximated by Euclidean
distances. If the data contain factor columns (e.g., using Gower's distance), then
the factors in \code{data} and \code{query} first need to be converted to numeric to use the
Euclidean approximation.
}
\examples{
## Example 1: use dbscan on the iris data set
data(iris)
iris <- as.matrix(iris[, 1:4])

## Find suitable DBSCAN parameters:
## 1. We use minPts = dim + 1 = 5 for iris. A larger value can also be used.
## 2. We inspect the k-NN distance plot for k = minPts - 1 = 4
kNNdistplot(iris, minPts = 5)

## Noise seems to start around a 4-NN distance of .7
abline(h=.7, col = "red", lty = 2)

## Cluster with the chosen parameters
res <- dbscan(iris, eps = .7, minPts = 5)
res

pairs(iris, col = res$cluster + 1L)

## Use a precomputed frNN object
fr <- frNN(iris, eps = .7)
dbscan(fr, minPts = 5)

## Example 2: use data from fpc
set.seed(665544)
n <- 100
x <- cbind(
  x = runif(10, 0, 10) + rnorm(n, sd = 0.2),
  y = runif(10, 0, 10) + rnorm(n, sd = 0.2)
  )

res <- dbscan(x, eps = .3, minPts = 3)
res

## plot clusters and add noise (cluster 0) as crosses.
plot(x, col = res$cluster)
points(x[res$cluster == 0, ], pch = 3, col = "grey")

hullplot(x, res)

## Predict cluster membership for new data points
## (Note: 0 means it is predicted as noise)
newdata <- x[1:5,] + rnorm(10, 0, .3)
hullplot(x, res)
points(newdata, pch = 3 , col = "red", lwd = 3)
text(newdata, pos = 1)

pred_label <- predict(res, newdata, data = x)
pred_label
points(newdata, col = pred_label + 1L,  cex = 2, lwd = 2)

## Compare speed against fpc version (if microbenchmark is installed)
## Note: we use dbscan::dbscan to make sure that we do now run the
## implementation in fpc.
\dontrun{
if (requireNamespace("fpc", quietly = TRUE) &&
    requireNamespace("microbenchmark", quietly = TRUE)) {
  t_dbscan <- microbenchmark::microbenchmark(
    dbscan::dbscan(x, .3, 3), times = 10, unit = "ms")
  t_dbscan_linear <- microbenchmark::microbenchmark(
    dbscan::dbscan(x, .3, 3, search = "linear"), times = 10, unit = "ms")
  t_dbscan_dist <- microbenchmark::microbenchmark(
    dbscan::dbscan(x, .3, 3, search = "dist"), times = 10, unit = "ms")
  t_fpc <- microbenchmark::microbenchmark(
    fpc::dbscan(x, .3, 3), times = 10, unit = "ms")

  r <- rbind(t_fpc, t_dbscan_dist, t_dbscan_linear, t_dbscan)
  r

  boxplot(r,
    names = c('fpc', 'dbscan (dist)', 'dbscan (linear)', 'dbscan (kdtree)'),
    main = "Runtime comparison in ms")

  ## speedup of the kd-tree-based version compared to the fpc implementation
  median(t_fpc$time) / median(t_dbscan$time)
}}

## Example 3: manually create a frNN object for dbscan (dbscan only needs ids and eps)
nn <- structure(list(ids = list(c(2,3), c(1,3), c(1,2,3), c(3,5), c(4,5)), eps = 1),
  class =  c("NN", "frNN"))
nn
dbscan(nn, minPts = 2)

}
\references{
Hahsler M, Piekenbrock M, Doran D (2019). dbscan: Fast
Density-Based Clustering with R.  \emph{Journal of Statistical Software,}
91(1), 1-30.
\doi{10.18637/jss.v091.i01}

Martin Ester, Hans-Peter Kriegel, Joerg Sander, Xiaowei Xu (1996). A
Density-Based Algorithm for Discovering Clusters in Large Spatial Databases
with Noise. Institute for Computer Science, University of Munich.
\emph{Proceedings of 2nd International Conference on Knowledge Discovery and
Data Mining (KDD-96),} 226-231.
\url{https://dl.acm.org/doi/10.5555/3001460.3001507}

Campello, R. J. G. B.; Moulavi, D.; Sander, J. (2013). Density-Based
Clustering Based on Hierarchical Density Estimates. Proceedings of the
17th Pacific-Asia Conference on Knowledge Discovery in Databases, PAKDD
2013, \emph{Lecture Notes in Computer Science} 7819, p. 160.
\doi{10.1007/978-3-642-37456-2_14}
}
\seealso{
Other clustering functions: 
\code{\link{extractFOSC}()},
\code{\link{hdbscan}()},
\code{\link{jpclust}()},
\code{\link{optics}()},
\code{\link{sNNclust}()}
}
\author{
Michael Hahsler
}
\concept{clustering functions}
\keyword{clustering}
\keyword{model}
