This is already very good code! Some improvements other than edist:
Using `each` for rank "0 like in the last line of kM_step should be
avoided, as it just boxes/unboxes the result unecessarily.
Instead of building up the groups per hand (I. & (= & s)), you can just
use `/.` to group the indices.
`?` already works on indices, so you can just use `4 ? #` instead of
`({~ 4 ? #) i. # x`.
I'm not sure how the original algorithm should work, but isn't the avarage
(+/%#) unneccesary as the length of the group is equal among its elements?
So +/ should be enough for comparison.
Tacifying your code then a bit results in:
kM2_step=: 4 : 0
groups=. (i. <./)@:{"1
sub=. {"1 {&x
best=. [ {~ [:(i. <./) [:+/"1 sub
(y groups x) best/. (i. # x)
)
kM2=: edist@] kM2_step^:_ (? #)
4 kM2 data
On Sat Feb 13, 2021 at 10:54 AM CET, Emir U wrote:
> Hi guys, I'm very new to J (about 6-7 hours experience), I'm coding a
> bunch of useful algos for clustering, optimisation and stats to give J a
> proper go: this is my first. I (think) I've coded the k-mediods PAM algo
> as described here: https://en.wikipedia.org/wiki/K-medoids
>
> I'm trying to tune my intuition as to what this code should look like
> when written properly. i.e. in canonical form. I'd be grateful for your
> feedback. I've enclosed the code below which is basically the kM_step
> and kM functions: the rest is testing code. If you run it it'll generate
> some data, cluster it and plot it for you.
>
>
> NB. UPDATE MEDIODS FROM DATA.
> kM_step=: 4 : 0
> d=. (x { "1 y)
> s=. ([@> (i. <./) each (;/ d )) { x
> idx=: I. & (= & s)
> d=. { "1 ({ & y)
> w=. (i. <./) & (+/%#) & d
> ; ((w { [) & idx) each x
> )
>
> NB. ITERATE UPDATE STEP TO CONVERGENCE.
> choose=: 4 : '({~ x ? #) ,y'
> kM=: 4 : '(kM_step & y) ^:_ x choose (i. #y)'
>
> NB. CALCULATE PAIRWISE EUCLIDEAN DISTANCE MATRIX.
> edist=: 3 : 0
> x=. +/ |: y^2
> a=. (,.x) +/ .+ (,:x)
> b=. y +/ .* (|: y)
> a - (2*b)
> )
>
> NB. TESTING: GENERATE DATA, FIT & PLOT.
> load 'plot'
>
> data=: ?(50 2$0)
> data=: data,3+(3*?(50 2$0))
> data=: data,5+(4*?(50 2$0))
> D=: edist data
> M=: (3 kM D) { data
>
> pd 'reset'
> pd 'type dot'
> pd 'pensize 3.1'
> pd 'color gray'
> pd ;/ |: data
> pd 'show'
> pd 'color red'
> pd 'pensize 4'
> pd ;/ |: M
>
> M
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm