Question: I need to cluster data-points in the form of X,Y,Phi. Right now I use DBSCAN (sklearn). The clustering works except for one thing: Phi is angular data, which is modulo 2\*Pi. As a result the clustering near Phi=0 is incorrect. Is there a trick to fix this? I could not find one or make one up myself that worked.

Thank you.

Answer: 
Circular boundary conditions are not easy to implement practically outside a Fourier framework.

You could try reparametrizing by replacing `X, Y, Phi` with `X, Y, a * cos(Phi), a * sin(Phi)`, where `a > 0`, a sort of scale factor, needs to be chosen correctly in order for this projection into 2D space to act the way you need in clustering. Start by checking `a = 1` (if it worked OK for pure `Phi`, then this is a good candidate) and then `a` on the order of magnitude of your remaining data `X, Y`.

The idea behind this is to replace `Phi` by its 'true' complex 'meaning' of *phase*, i.e. `exp(1j * Phi)`, but keeping it real all the while.

You then proceed to calculate a distance based on this reparametrization, e.g. euclidean:

```
dist = ((np.array([X1, Y1, a* np.cos(Phi1), a * np.sin(Phi1)]) - np.array([X2, Y2, a * np.cos(Phi2), a * np.sin(Phi2)])) ** 2).sum()

```

This you do for every pair before feeding it to your DBSCAN object.
DBSCAN can work with *arbitary distances*.

So first define a distance function (which will likely involve some trigonometric functions), then plug this into DBSCAN as similarity.

You could probably use something like this:

```
distance = (x1-x2)**2 + (y1-y1)**2 + factor * sin(phi1-phi2)**2

```

but you need to carefully choose your weight `factor`, as the angular difference is on a different scale as your `X` and `Y` axes, I guess.

Don't use Euclidean distance on this data set, for the obvious reasons.