Tag Info

Hot answers tagged

23

Finding the cluster centers is the hard part. There are zillions of ways to do this, such as standardizing $(x,y,t)$ and applying some (almost any) kind of cluster analysis. But these data are special: the eye movement has a measurable speed. The gaze is resting if and only if the speed is low. The threshold for "low" is physically determined (but can ...


21

ClusteringComponents is indeed the function to go for. To get the same results as MATLAB you need to do the following: x = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}, {16, 17, 18, 19, 20}, {21, 22, 23, 24, 25}}; cc = ClusteringComponents[x, 2, 1, Method -> "KMeans", "DistanceFunction" -> SquaredEuclideanDistance, ...


17

Since Mr.Wizard mentions that ClusteringComponents is unavailable in Mathematica 7, here's an implementation of Lloyd's algorithm for k-means clustering (can also be interpreted as an Expectation-Maximization approach) that will run on version 7. Clear[kmeans] kmeans[list_, k_, opts : OptionsPattern[ {DistanceFunction -> SquaredEuclideanDistance, ...


17

I think FindClusters is ideal tool. It just needs slight tweaking. One of your data sets: data = gazeSeq[3][[All, ;; 2]]; This works: Show[ ListPlot[#, PlotStyle -> PointSize[.003]], Graphics[{Red, Thick, Circle[#, .3]}& /@ Mean/@ #], AspectRatio -> Automatic, PlotRange -> All, Frame -> True, Axes -> False ]& @ ...


13

In version 7 and 8 you have MorphologicalComponents which can do this. Its default Method (version 8) is "Connected" with 8 point connectivity being the default (you can switch this off with the option CornerNeighbors->False). So, this seems ideally suited to your requirements. An example from the MorphologicalComponents doc page:


13

Here is an image processing solution that gives you the following result for the 7 different datasets: Approach: First, we plot it without any frames or axes and convert to a binary image. plotRange = Function[xy, #[gazeSeq[2][[All, xy]]] & /@ {Min, Max}] /@ {1, 2}; img = Image@ListPlot[gazeSeq[2][[All, ;; 2]], Axes -> False, PlotRange -> ...


12

This is a straightforward application of FindClusters: ListPlot@FindClusters[#, 2] & /@ Transpose@PairSet // GraphicsRow See the DistanceFunction and Method options to further fine tune your clustering or use a different metric.


11

Based on the data you provide, it seems that hierarchical clustering (see wiki here) with type "agglomerate" (bottom up) solves your problem, i.e.: out = FindClusters[data, 6, Method -> "Agglomerate"]; ListPointPlot3D[out] and get: Based on how your full dataset looks like (e.g. if you know how many clusters there are etc.), you might need to adapt ...


11

DendrogramPlot accepts Axes as an option. Despite syntax highlighting in red of Axes and AxesOrigin, GridLines etc. these options seem to work with DendrogramPlot. Inter-cluster distance in a Cluster object is given as the third element. Several combinations of DistanceFunction and Linkage where inter-cluster distances are highlighted in red and shown as ...


11

Your data seems to be composed of two components: An offset for each x-location (or an offset-function of x) and a density relative to that offset. If you had either of the two, estimating the other would be easy. Right so far? One common solution for this kind of problem is the EM algorithm. Basically, you start with some estimate for one variable (e.g. ...


11

This generates a 20 by 20 binary matrix and finds the morphological components. SeedRandom[11]; m=RandomInteger[{0,1},{20,20}]; a=MorphologicalComponents[m,CornerNeighbors->False] Notice that morphological component 2, in row 1, col 6, abuts morphological component 42 in row 20, col 6. Morphological components 2 and 39 abut in column 8. These ...


10

Try this: First, set the distance threshold. d = 0.1; The main function uses Fold, which, along with its companion FoldList and MapThread, is one of the most useful "functional" functions in the language. test = Fold[If[EuclideanDistance[Most@#2, Mean[Most /@ Last[#1]]] < d, Join[Most[#1], {Join[Last[#1], {#2}]}], Join[#1, {{#2}}]] &, ...


9

The problem is that your "Background" is not a cluster with the usual distance function. You can tweak it (to some extent) with something like: data1 = RandomReal[{-0.1, 0.1}, {10^2, 2}]; data2 = RandomReal[{-1, 1}, {2*10^2, 2}]; data3 = RandomReal[{-0.3, -0.2}, {2*10^2, 2}]; data5 = Join[data1, data2, data3]; ListPlot[FindClusters[data5, ...


9

Here's some code implementing the purely local strategy suggested in my comment. points = << "~/tmp/Plot B Points.txt"; xwidth = 200; ywidth = 0.1; binnedPoints = Partition[points, xwidth]; histograms = BinCounts[#, {Min@points, Max@points, ywidth}] & /@ binnedPoints; align[a_, b_] := First@Ordering[ListCorrelate[a, b, {-1, 1}, 0], -1] - Length@a; ...


8

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, ...


8

You can get the same results with: FindClusters[pts, Method -> {"Agglomerate", "Linkage" -> "Complete", "SignificanceTest" -> {"Gap", "Tolerance" -> 3}}] But it is impossible to test its significance until you post more point sets.


8

Clustering is a relatively unstable process. Points which exist near to cluster boundaries may have small Euclidean, or other, distances between them, but be on different sides of the local boundary. So, in and of themselves, point separation distance metrics may be misleading. If clusters in the data overlap to any degree, a common case, then there is ...


8

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 ...


7

One possible approach is to look for a larger number of clusters, so that the background is split into multiple clusters. c = FindClusters[data5, 8]; ListPlot[c] The data clusters will be those with a larger number of members and smaller size (not necessarily true - see update) ListPlot[ Transpose[{{Length /@ c, Sqrt[Total[Variance[#]]] & /@ c}}, ...


7

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 -> ...


7

I tested ClusteringComponents with the examples provided in the Documentation Center (http://reference.wolfram.com/mathematica/ref/ClusteringComponents.html) of Mathematica. In Options > DistanceFunction there is an example provided how to use your own DistanceFunction in ClusteringComponents: ClusteringComponents[{{1, 2}, 3, {10, 11}, {12, {13}}, 14}, 2, ...


7

This is roughly 30 times faster than your approach and can be tuned easier than FindClusters[]: getOneCluster[pts_List, maxDist_?NumericQ] :=(*Returns a cluster*) Module[{f}, f = Nearest[pts]; FixedPoint[Union@Flatten[f[#, {Infinity, maxDist}] & /@ #, 1] &, {First@pts}]] clusters[data_] := Module[{f, dist}, (* Some Characteristic Distance, ...


6

If you want something like this : (colors are random) the code is : dendogram = DendrogramPlot[data, LeafLabels -> Range[12], HighlightLevel -> 3, HighlightStyle -> {Red, Green, Blue}]; Show[ dendogram, Graphics[(Cases[dendogram, Rectangle[___], {1, Infinity}] // SortBy[#, -#[[2, 2]] &] & ) /. x : ...


5

It is probably easier to keep track of the days in each cluster if you use FindClusters like this: loadclust = FindClusters[load -> Range[365], 4]; This returns the clusters in terms of day numbers instead of the full load curve for that day, e.g. loadclust // Shallow {{1, 5, 10, 15, 23, 26, 30, 32, 36, 41, <<75>>}, {2, 3, 6, 9, 11, 12, ...


5

Apart from the output format, the main differences are: FindClusters can take a custom DistanceFunction whereas ClusteringComponents can only use those listed in the documentation FindClusters works with strings and lists of True/False but ClusteringComponents only takes numerical arrays FindClusters takes a 1D list as input, ClusteringComponents can take ...


5

As a first simple way: data=ReadList["points.txt",{Number,Number,Number}]; dataG=Gather[data,EuclideanDistance[#1,#2]<0.5&] ListPointPlot3D[dataG,PlotStyle->Directive[PointSize[0.01]] ,BoxRatios->{1,1,1}] But this do not consider the grid structure. And later I discovered here why this is not a good way. Another more precise one is: ...


5

Straightforward approach with controlling related heights. Needs["HierarchicalClustering`"] SeedRandom@2; data = RandomVariate[NormalDistribution[], {10, 20}]; height = 50; label = ListPlot[#, Axes -> False, Joined -> True, ImageSize -> {300, height}, AspectRatio -> height/300] & /@ data; Edit I'm sorry my previous ...


4

If you don't want to compute every pair-wise distance, one thing is to compute the Delaunay triangulation of all the points in the sets, this tends to be only ${\cal{O}}(n \log n )$ computation intesive. We will use the ComputationalGeometry package for the Delauny triangulation. There are other faster options described in this site, also this package does ...


4

This is a possible cohesion measure. Please note that your problem isn't defined enough in mathematical terms, so perhaps you are looking for a statistical measure like Variance[] or StandardDeviation[]. Anyway: cohessionCoef[pts_] := Mean[Flatten[Function[{x}, Table[1/EuclideanDistance[#, i], {i, x}]] [Nearest[Complement[pts, {#}], #, 8]] & ...


4

Here's a different approach, though I think it's quite inefficient. I treat the points as vertices in a graph. I check each pair of points and if the distance between them is less than 1.5 I connect them with an edge. The clusters are just the ConnectedComponents of the graph. v = Range @ Length @ data; e = UndirectedEdge @@@ Select[Subsets[v, {2}], ...



Only top voted, non community-wiki answers of a minimum length are eligible