# Why doesn't FindClusters find any clusters in this case?

I am trying to use FindClusters to segment data points into similar numbers but so far I couldn't get it work for this example:

l = {110, 111, 115, 117, 251, 254, 254, 259, 399, 400, 401,
402, 542, 546, 549, 554, 660, 660, 660, 660};
FindClusters[l]
(*
-> {{110, 111, 115, 117, 251, 254, 254, 259, 399, 400, 401, 402, 542,
546, 549, 554, 660, 660, 660, 660}}
*)


If I set the N parameter (to specify: Exactly N clusters), it works:

FindClusters[l, 5]
(*
-> {{110, 111, 115, 117}, {251, 254, 254, 259},
{399, 400, 401, 402}, {542, 546, 549, 554}, {660, 660, 660, 660}}
*)


However, my intent was to use FindClusters to figure out N.

-
You've tried playing around with various DistanceFunction settings? DistanceFunction -> BrayCurtisDistance and DistanceFunction -> CanberraDistance work here, for instance... – J. M. Oct 27 '12 at 17:10
@J.M. Sorry, posted an answer simultaneously – Dr. belisarius Oct 27 '12 at 17:13
@bel, no prob, though I have a feeling we got lucky, and these only work for the particular case that OP presented, since OP says nothing more about the nature of the actual data... – J. M. Oct 27 '12 at 17:15
@J.M. added a "testing framework" (so to speak) – Dr. belisarius Oct 27 '12 at 17:37
Thanks for your answers! I am still trying to figure out why EuclideanDistance doesn't work in this case. @J.M.: context is a an OCR algorithm I am trying to implement. I am trying to normalize a grid that has been estimated by WatershedComponents (See my other question) . It's probably too complex to include here. – Sven K Oct 27 '12 at 17:45

Use the Bray-Curtis distance Total[Abs[u-v]]/Total[Abs[u+v]]:

FindClusters[{110, 111, 115, 117, 251, 254, 254, 259, 399, 400, 401,
402, 542, 546, 549, 554, 660, 660, 660, 660},
DistanceFunction -> BrayCurtisDistance]
(*
{{110, 111, 115, 117},
{251, 254, 254, 259},
{399, 400, 401, 402},
{542, 546, 549, 554},
{660, 660, 660, 660}}
*)


Edit:

Here you have an experimental setup to test the FindClusters[] options in problems like yours:

l1 = RandomInteger[{100, 1000}, 10];
l2 = Join @@ (IntegerPart /@ RandomVariate[NormalDistribution[#, 10], 10] & /@ l1);
l3 = FindClusters[l2, DistanceFunction -> CanberraDistance];
Framed@Show[MapIndexed[
Graphics[{ColorData[3][#2[[1]]],
Line[{{#, 0}, {#, 1}}] & /@ #1}] &, l3],
PlotRange -> {0, 1}, AspectRatio -> 1/5]


-
Neat addition. :) OP should now be able to play around with the Method and DistanceFunction options easily, to see what suits his data best. – J. M. Oct 27 '12 at 17:39

I'm not really sure why the default option for FindClusters with EuclideanDistance and Method->"Optimize" fails to distinguish any clusters.

Here are some results which might add a little detail:

Here are the numeric distance functions:

dfs = {EuclideanDistance, SquaredEuclideanDistance, NormalizedSquaredEuclideanDistance,
CosineDistance, CorrelationDistance}


Applying the various distance functions and methods:

Length@FindClusters[l, DistanceFunction -> #, Method -> "Agglomerate"] & /@ dfs
Length@FindClusters[l, DistanceFunction -> #, Method -> "Optimize"] & /@ dfs


{5, 1, 1, 5, 5, 5, 5, 1, 1} {1, 1, 1, 1, 1, 5, 5, 1, 1}

And in tabular form:

So it is possible to use the EuclideanDistance function for this data, but only with agglomerative clustering.

-