1CLASS:: KMeansRT
2summary:: k-means classification in real time
3categories:: UGens>Analysis
4related:: Classes/KMeans, Classes/NearestN
5
6DESCRIPTION::
7
8Performs online k-means classification, classifying each datapoint that comes in and updating the k-means centroids.
9
10The method is described in Algorithm B.1 of Brian McFee's 2012 thesis (http://cseweb.ucsd.edu/~bmcfee/papers/bmcfee_dissertation.pdf ). McFee calls it "online Hartigan k-means".
11
12
13CLASSMETHODS::
14
15METHOD:: kr
16argument:: bufnum
17a Buffer with "k" frames and "d + 1" channels (where d is the number of dimensions of input data. Each frame of the Buffer will hold data for a centroid (the centroid location, plus the final channel holds the effective number of points associated with the centroid).
18
19argument:: inputdata
20An array representing the input point. Num channels must match the dimensionality of the points in the dataset.
21
22argument:: k
23k is the number of centroids.
24
25argument:: gate
26The unit is active while gate > 0. While <=0, no search is performed and output is held steady
27
28argument:: reset
29If reset is greater than 0, the "flexibility" of the centroids is reset back to initial values (as if no data had been received).
30
31argument:: learn
32Controls whether the unit is learning from its input. If you set this to zero it will not learn, but will still output decisions. This is useful for applying a previously-learned clusterer without modifying it.
33This argument cannot be modulated: each time you use KMeansRT it is either learning from scratch, or using a fixed pre-learnt buffer.
34
35returns:: the cluster index with which the input datapoint has been associated.
36
37
38METHOD:: getCentroid
39A convenience method (just a wrapper round BufRd really) that lets you access the centroid location, given a cluster index.
40argument:: bufnum
41the same buffer as is passed to .kr
42argument:: classif
43the classification index, i.e. the output from .kr
44argument:: ndims
45the number of dimensions ("d" in the above description)
46returns:: the "d"-dimensional current location of the centroid corresponding to index "classif".
47
48EXAMPLES::
49
50This example clusters every frame of a sound sample, using the spectral centroid of each frame, and sonifies the result:
51
52code::
53s.boot;
54k = 5;
55~ndims = 1;
56b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
57~kbuf = Buffer.alloc(s, k, ~ndims+1)
58
59(
60x = {
61	var sig, chain, chaintrig, features, kbuf, classif, centroid, resynth;
62
63	// sig = AudioIn.ar;
64	sig = PlayBuf.ar(1, b, loop: 1);
65	chain = FFT(LocalBuf(512), sig);
66	chaintrig = chain > -0.001;
67
68	features = [SpecCentroid.kr(chain)]; // just one 1D feature here
69	classif = KMeansRT.kr(~kbuf, features, k, chaintrig);
70	classif.poll(chaintrig);
71
72	// Now we read the centroid position back out of the buffer and sonify
73	centroid = KMeansRT.getCentroid(~kbuf, classif, ~ndims).at(0);
74
75	resynth = SinOsc.ar(centroid, 0, 0.1);
76	[sig, resynth]
77}.play
78)
79
80x.free
81::
82
83This example clusters onsets:
84
85code::
86s.boot;
87k = 5;
88~ndims = 1;
89// Specify a stereo music recording you have locally.
90b = Buffer.cueSoundFile(s, "~/back_to_black.wav".standardizePath, 0, 2);
91~kbuf = Buffer.alloc(s, k, ~ndims+1)
92
93(
94x = {
95	var sig, chain, trig, features, kbuf, classif, centroid, resynth;
96
97	sig = DiskIn.ar(2, b.bufnum);
98
99	chain = FFT(LocalBuf(1024), sig.mean);
100	trig = Onsets.kr(chain);
101
102	features = [SpecCentroid.kr(chain)]; // just one 1D feature here
103	classif = KMeansRT.kr(~kbuf, features, k, trig);
104	classif.poll(trig);
105
106	resynth = Pulse.ar(classif.linexp(0, k, 100, 1000)) * 0.9 * EnvGen.ar(Env.perc, trig);
107	sig + resynth
108}.play
109)
110
111x.free;
112b.close; b.free;
113::
114
115