0

I am trying to cluster some data that seems to be separable using COSINE instead of Euclidean distance. How can I use MATLAB's selforgmap for this purpose? I don't believe it is through 'distanceFcn' option.

x = simplecluster_dataset; net = selforgmap([8 8],100,3,'hextop','cosine'); net = train(net,x); view(net) y = net(x); classes = vec2ind(y);

2
  • where is your tried codes? Commented Nov 27, 2016 at 16:20
  • @Sachith I added an example. Commented Nov 27, 2016 at 19:06

2 Answers 2

2

You are talking about a custom distance function. I believe that distancefcn is indeed the right place to look. But making alternative distance functions for MATLAB's implementation of SOM does not appear to be documented.

The default value of nntype.distanceFcn is 'linkdist'. Here are the neural network toolbox distance functions:

>> help nndistance Neural Network Toolbox Distance Functions.

boxdist  - Box distance function.
dist     - Euclidean distance weight function.
linkdist - Link distance function.
mandist  - Manhattan distance function.

As we can find:

>> help nncustom:

Distance Functions... Use dist and its package of subfunctions +dist as templates.

Well, it's a little helpful, because now we know how we would implement a custom function. When we open the file dist, then try to "Save As" we can find its package location. For me on Windows, this is: C:\Program Files\MATLAB\R2015b\toolbox\nnet\nnet\nndistance

Basically to make a custom distance measure, we need to use dist.m and rewrite all the 16 functions in the folder +dist to suit the new distance measure. It's not enough to update the distance function itself (which is implemented in +dist/apply.m) but we must also update the derivatives `+dist/dz_dp.m'.

The easiest way to use a cosine similarity distance would be through a normalised dot product. Instead of doing what dist does (p' * p), we would instead like to use statistical toolbox pdist(p, 'cosine'). I'd like to think that the weight function normprod would give some help in writing the custom distance function, but it is not sufficient. Also, sadly the neural network toolbox is not commented. The code for dist was written in 2005 so it seems like Mathworks is not active in this field. Personally I use SOMToolbox, but it does not have cosine distance functions, either.

I searched the Internet but was unable to find anyone else who has implemented a custom distance function. I tried to modify the weight function normprod for this purpose, but an internal check is apparently failing somewhere (error COSDIST.dz_dp is not consistent with numerical derivative.)

TLDR: I think the answer is to either use one of the four built in distance functions or write a custom distance function.

Sign up to request clarification or add additional context in comments.

3 Comments

A third option does come to mind, which is normalising each of the inputs to the unit circle, then using the Euclidean distance. The result would be similar to the cosine distance, although missing a squaring. See stats.stackexchange.com/questions/146221/…
e.g. replacing the lines in your code above with net = train(net,normc(x)); and y = net(normc(X))
This type of normalisation in SOM is discussed here: stackoverflow.com/questions/13687256/…
0

I believe I can provide a useful input here: instead of rewriting/adding the dist folder, you can access the layer of you network via net.layers{1}.distanceFcn after initialization and manually set the distance function you would like. This way, your code will work on any machine.

That would be net.layers{1}.distanceFcn = yourdistancefunction. You will still have to write yourdistancefunction yourself if it doesn't already exist.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.