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