My ultimate aim is to have a function which I can feed into scikit-learn's NearestNeighbor class as a custom metric parameter.

Existing packages

I have been researching existing libraries for a while.

The only thing I found was this KMeans package, for python 2 and based on implementing a C library. I could neither load it in with ctypes nor convert it into an executable with gcc.

I also found this other C code and this Matlab script but with similar results.


I also looked into a few papers, to see if I can implement it by myself. For instance, based on this I understand that the main thing I need to do is to calculate the tangent matrix. But, I do not understand

  • how do I define $s(p, \alpha)$ and especially
  • how do I calculate the derivatives in python.

I would be glad for any help, comment, whatsoever.


As suggested, I raised the following related issues/requests:

Update 2

@ComeOnGetMe rewrote his code so it can be used along the scikit-learn specifications (example code). Many thanks for that! Nonetheless, when I tried to use it in scikit-learn it underperformed and was very slow, so there is further work needed with that.

Since then I also found a more detailed explanation for code implementation, although based on the C code already mentioned.


I would just repeat my reply under the original issue in case anybody is looking for the answer here.

The direct answer to the issue:

I can't really recall how I used this code 2 years ago. But I got it working with two steps:

  1. Build the shared library with gcc -fPIC -shared st.c -o ts.so.
  2. Change the .so path in tangentDistance.py to the absolute path of the ts.so file.

I have just updated the code so that you can run it directly after compiling the .so file in the root directory.

A bit of comment on this repo:

Clearly this library is not well designed and filled with so much hardcodes. You can't really use it if you are not doing exactly the same task as I was doing: k-means clustering on MNIST dataset. If you want it to be more general and better fit your purposes just let me know.

  • $\begingroup$ Great, many thanks for this! I try to build the shared library, but got another error message: gcc: error: st.c: No such file or directory // gcc: fatal error: no input files // compilation terminated. I suppose I would need to reinstall gcc for this? I continue to investigate and will get back if have some results. $\endgroup$
    – nocibambi
    Dec 2 '18 at 21:43
  • $\begingroup$ By 'root' I mean the root of the repository where the st.c file is located. $\endgroup$ Dec 2 '18 at 21:57
  • 2
    $\begingroup$ BTW You don't need to compile it since I have pushed the .so file. Just pull from the repo and you are good to go. $\endgroup$ Dec 2 '18 at 21:58
  • $\begingroup$ Thanks for this. I detailed my experiences on your KMeans package's github page. $\endgroup$
    – nocibambi
    Dec 2 '18 at 23:35

ComOnGetMe's KMeans tangent distance metric looks good, if it didn't work for you initially you should fork it and work on the code. I would contact him directly, he probably would have insight for you. Scikit-learn doesn't have a distance metric for tangent distances but the documentation states you can call a user-defined distance (all be it with overhead).

Contributing code might be a good direction to go if you would want to contact scikit-learn's developers and there are a couple of researchers with published papers implementing tangent distance as a metric, so you could have luck there too.

  • 1
    $\begingroup$ Thanks for this! I raised these issues as you suggested (see the links at the end), but to fork/contribute I still would need to understand how should I do it. [1]: github.com/ComeOnGetMe/… [2]: github.com/scikit-learn/scikit-learn/issues/12711 $\endgroup$
    – nocibambi
    Dec 2 '18 at 10:07
  • 1
    $\begingroup$ The paper I linked by some researchers who implemented it explains it pretty throughly. Basically it's a local linearity metric that scales using the jacobian determinant and uses a tangent transform. If you're familiar with manifold learning and take a look at [Tangent_space](en.wikipedia.org/wiki/Tangent_space) you can see the theoretical implications to distance metrics. Contributing to the code is more-or-less a process of studying it and getting it to work, which isn't something I can help out with on stackexchange, but I hope you do get it working! $\endgroup$ Dec 3 '18 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.