-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathKMeans.st
87 lines (64 loc) · 3.04 KB
/
KMeans.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Object subclass: #KMeans instanceVariableNames: 'iterations clusters' classVariableNames: '' poolDictionaries: '' category: 'KMeans'!!KMeans commentStamp: 'RoelWuyts 3/31/2016 09:37' prior: 0!I implement an idiomatic version of the kmeans algorithm in order to compare to implementations in other languages - see https://github.com/andreaferretti/kmeans .To use me:- download Pharo and launch an image. - put the points.json in the same directory than the image. - type "KMeans benchmark: 100" (in the Playground or anywhere else), - select the text and 'Print it' in the contextual menu.- wait...!!KMeans methodsFor: 'algorithm' stamp: 'AndreaFerretti 10/8/2014 18:57'!run: points
| centroids |
centroids := points first: clusters.
iterations timesRepeat: [
centroids := (self cluster: points around: centroids) collect: [ :each | each average ]
].
^ self cluster: points around: centroids! !!KMeans methodsFor: 'algorithm' stamp: 'RoelWuyts 3/1/2016 09:51'!cluster: points around: centroids
^ (points groupedBy: [ :p | p closestFrom: centroids ]) values! !!KMeans methodsFor: 'algorithm' stamp: 'AndreaFerretti 10/8/2014 19:01'!run: points times: times
times timesRepeat: [ self run: points ].! !!KMeans methodsFor: 'benchmarks' stamp: 'AndreaFerretti 10/8/2014 19:03'!benchmark: points repeating: repetitions
| time |
time := Time millisecondsToRun: [ self run: points times: repetitions ].
^ time / repetitions.! !!KMeans methodsFor: 'initialization' stamp: 'RoelWuyts 2/29/2016 17:07'!clusters: numClusters iterations: numIterations
iterations := numIterations. clusters := numClusters! !"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!KMeans class instanceVariableNames: ''!!KMeans class methodsFor: 'benchmarks' stamp: 'RoelWuyts 3/31/2016 09:24'!benchmark: repetitions pointsFilename: pointsFilename "self benchmark: 100 pointsFilename: 'points.json' " | fileref str points | fileref := pointsFilename asFileReference. str := FileStream readOnlyFileNamed: fileref. points := (MCFileTreeJsonParser parseStream: str) collect: [:arr | Point x: arr first y: arr second ]. ^(self clusters: 10 iterations: 15) benchmark: points repeating: repetitions! !!KMeans class methodsFor: 'benchmarks' stamp: 'RoelWuyts 3/31/2016 09:25'!benchmark: repetitions "self benchmark: 100" ^self benchmark: repetitions pointsFilename: self pointsFilename ! !!KMeans class methodsFor: 'benchmarks' stamp: 'RoelWuyts 3/31/2016 09:23'!pointsFilename "The name and location of the file that contains the points used for the benchmarking." "By default it is assumed to be next to your Pharo image." ^'points.json'! !!KMeans class methodsFor: 'instance creation' stamp: 'RoelWuyts 2/29/2016 17:09'!clusters: numClusters iterations: numIterations ^self new clusters: numClusters iterations: numIterations! !'From Pharo4.0 of 18 March 2013 [Latest update: #40626] on 31 March 2016 at 9:37:42.371164 am'!!Point methodsFor: '*KMeans' stamp: 'RoelWuyts 3/1/2016 09:57'!closestFrom: points
^ points detectMin: [:p | self dist: p ]! !