Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm having some problems clustering data in a 2D spectra and will really appreciate some help. I've been playing around with the FindClusters function but wasn't able to tune it appropriately. Maybe someone can give me a hand on how to customize the DistanceFunction option or so.

A sample of my data looks like this:

Sample data

Ideally I would want the peaks to be clustered as this:

Ideal clustering

I tried the FindClusters functions with different parameters but only got partial clusters like these:

Partial clusters

I believe it may be easy if I can define my own DistanceFunction but I don't understand how to use a custom function there with a threshold or so.

I've seen other posts like this one, this other one and this one too but I wasn't able to successfully apply those methods.

It doesn't matter if I don't get that red circle clustering like the ideal image. If I can just get to identify the whole clusters, I can reduce that set to just one point that would be the center of gravity.

It would be awesome if you can point me the way on how to solve this. You can download that sample from here.

Just one thing, I don't know before hand how many clusters I'll get. I believe there are 30 in this dataset but this is just a sample. Thank you!!

share|improve this question
    
I will give you two links to read First and Second –  Sektor Sep 1 '13 at 2:02
    
Those were the first things I read but couldn't understand how a custom DistanceFunction works –  xtian777x Sep 1 '13 at 2:27
    
Well, you need to make up your mind how do you want to partition the set of data/measurements. You need to define a metric and based on that proceed with implementing the DistanceFunction[]. Long story - short - on what similar characteristic do you plan to partition the set of data ? –  Sektor Sep 1 '13 at 2:41
    
OK, let's say I use the default EuclideanDistance function, how do I know what is the threshold it's using to discriminate? Like "points with distance < 0.5 between them are considered a cluster"? My guess is that, if the DistanceFunction f satisfies f(ei,ej)>0, I would have to make a function that, for distances greater than 0.5 => f(ei,ej)<0. In that sense, f will no longer fulfill the condition and those points will be left outside the cluster. Makes sense? Thanx! –  xtian777x Sep 1 '13 at 2:55
    
To answer the question what threshold is used in the algorithms you should read this general method Link –  Sektor Sep 1 '13 at 3:25
add comment

2 Answers

up vote 2 down vote accepted

Inspired by Murta answer I have this one:

Get["https://dl.dropboxusercontent.com/u/81954930/datapairs.m"];
Manipulate[
  With[{list = 
   Join @@ (Split[
     SortBy[#, Last], (Abs[(#1[[2]] - #2[[2]])] < limY) &] & /@ 
     Gather[datapairs, Abs[(#1[[1]] - #2[[1]])] < limX &])}, 
   Column[{ListPlot[list, ImageSize -> 400], 
    Row[{"Number of clusters:", Length[list]}]}]]
  , {{limY, 5}, 0, 50}, {{limX, 5}, 0, 50}]

manipulate output

I split first by column and then by the other axis.

share|improve this answer
add comment

This can be a first step.

Get["https://dl.dropboxusercontent.com/u/81954930/datapairs.m"]
Manipulate[
 dataC = Mean /@ Gather[datapairs, EuclideanDistance[#1, #2] < lim &];
 p1 = ListPlot[datapairs];
 p2 = ListPlot[dataC, PlotStyle -> Directive[Opacity[0.5], PointSize[0.02], Red]];
 Show[p2, p1]
 , {lim, 5, 50, 10}
 ]

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.