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... Commented Oct 27, 2012 at 17:10
• @J.M. Sorry, posted an answer simultaneously Commented Oct 27, 2012 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... Commented Oct 27, 2012 at 17:15
• @J.M. added a "testing framework" (so to speak) Commented Oct 27, 2012 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. Commented Oct 27, 2012 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. Commented Oct 27, 2012 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.