# Clustering a bivariate data set with Mathematica

I need to partition a bivariate data set into predetermined "n" clusters and, at the same time, to fix the centroid position of each cluster. Is the ClusteringComponents function useful?

Thanks BR for your help. I will use your example to explain better my question I want to Split your “data” into two (n=2) clusters. Previously, I want to fix the coordinate (centroids) of the two clusters.

data = With[{ρ = -0.4},
RandomVariate[BinormalDistribution[{-1, 1}, {1, 2}, ρ], 10000]];

FIXEDcentroids = {{-2, 0}, {0.5, -0.4}};

Show[ListPlot[data, Frame -> True, Axes -> False],
ListPlot[FIXEDcentroids, Frame -> True, PlotStyle -> {Black, PointSize[0.02]}]]


The next step should be to "force" the clustering process to split the “data” set according the position of the two predefined centroids.

If I use the FindCluster traditional form:

NumberOfCluster = 2;
clusterdata = FindClusters[data, NumberOfCluster];


I obtained two new centroids.

centroidFindClusters = Mean[#] & /@ clusterdata


Obviously the two new centroids are differents from those that I preselected (i.e. FIXEDcentroids). Therefore I am not able to solve my problem.... ...if were possible to write: FindClusters[data, FIXEDcentroids] it would be perfect......

• Welcome to mma.SE! If you edit the question with some example code and example data, I'm sure you'll get even better answers (please format your code by indenting it by four spaces or by using back-ticks () . Sep 13 '12 at 7:28
• Without more information about your exact problem, it's hard to say, but in short, yes. You might also want to look at the FindClusters function. Sep 13 '12 at 7:52
• By the way, welcome, and please consider registering your account. That way, any upvotes you get on this question are added to those you might get on future questions and answers. Then over time you will be able to do more on the site (post graphics, edit things, etc). Sep 13 '12 at 7:53
• Welcome Andrea! Please supply us with a workable data set and a concise summary of what exactly you´d like to achieve and what you´ve tried so far. Have a look at other popular questions (recent sample) to get a feeling how this could look like. Sep 13 '12 at 9:24
• There's no guarantee that a clustering exists which has the cluster means that you specify. Are you trying to minimize the distance from the cluster means to the FIXEDcentroids? Sep 13 '12 at 15:45

This may give you a start. Code below is built on an example from this page, where you can find more very neat stats examples. Get some data on duration of Old Faithful geyser eruptions and construct a distribution based on it:

data = ExampleData[{"Statistics", "OldFaithful"}];
\[ScriptCapitalD] = KernelMixtureDistribution[data, "SheatherJones"];


Now simulate eruptions based on this distribution:

rng = RandomVariate[\[ScriptCapitalD], 500];


The data are bi-variate and split into 2 main clusters. Use FindClusters to separate them (red and black):

Show[SmoothDensityHistogram[rng, ColorFunction -> "TemperatureMap"],
ListPlot[FindClusters[rng, 2], PlotRange -> {{1, 6}, {30, 110}},
AspectRatio -> 1, Frame -> True, ImageSize -> 220,
PlotStyle -> {Red, Black},
PlotLabel -> Text[Style["Simulated Eruptions", FontFamily -> "Verdana", Bold]],
Background -> Directive[Opacity[.5], White], Axes -> None]] Here is an alternative visualization:

p2 = ListPlot[FindClusters[rng, 2], PlotRange -> {{1, 6}, {30, 110}},
AspectRatio -> 1, Frame -> True, ImageSize -> 220,
PlotStyle -> {Red, Black},
PlotLabel ->
Text[Style["Simulated Eruptions", FontFamily -> "Verdana", Bold]],
Background -> Directive[Opacity[.5], White], Axes -> None];

p1 = Plot3D[Evaluate[PDF[\[ScriptCapitalD], {x, y}]], {x, 1, 6}, {y, 30, 105},
Mesh -> 25, PlotRange -> All,
PlotLabel -> Text[Style["Duration vs. Waiting Time", FontFamily -> "Verdana",
Large]], BoxRatios -> 1, PlotPoints -> 100,
MeshStyle -> Opacity[.3], ColorFunction -> "TemperatureMap",
Boxed -> False, ViewPoint -> {2, -2, 1},
Epilog -> Inset[p2, {Right, Bottom}, {Right, Bottom}], ImageSize -> 570] Here I can give you some direction!

## Bi-variate Data

We draw random data from a built-in distribution in MMA. First see the PDF of our BinormalDistribution. Now we draw some $10000$ data sample and visualize it using ListPlot

data = With[{\[Rho] = -0.4},
RandomVariate[BinormalDistribution[{-1, 1}, {1, 2}, \[Rho]],10000]];
ListPlot[data, Frame -> True, Axes -> False] ## Clustering..

Now MMA does the clustering with in a blink! We save the $n$ say $(=10)$ cluster in clusterdata.

NumberOfCluster = 10;
clusterdata = FindClusters[data, NumberOfCluster];
centroid = Mean[#] & /@ clusterdata;


## Visualize!

We can show the centroids as well as the handy PolytopeQuantile for each clusters.

Needs["MultivariateStatistics"];
quantile = 0.8;
col = RGBColor[#] & /@ RandomReal[{0, 1}, {NumberOfCluster, 3}];
ListPlot[#1, Frame -> True, Axes -> False,
PlotStyle -> #2] &, {clusterdata, col}],
Epilog -> {Directive[Black], PointSize[Large], Point[centroid]},
PlotRange -> All]}~Join~
` 