Non-negative Matrix Factorization for Ruby

Filed in: Ruby Add comments

Several months back I needed to compute NMF of some relatively larges matrices.
Since the native Ruby code was painfully slow, and for some reason even failed to work for some matrices, I decided to write a C implementation which will leverage the GNU Scientific Library (GSL) and then wrap it for using in Ruby application.
It was a neat add-on to the rb-gsl ruby library. What it does is adding NMF module under the GSL::Matrix, and there you have a method nmf which receives a GSL::Matrix and number of columns as a parameter and then returns two matrices.
Since this is an iterative algorithm, the number of runs is limited to 1000, and the desired difference cost metric is set to 10-6.
I tried to contact the author and even posted my code in the issue tracker, but haven’t received any response at the time of writing.
So I decided to create a git-svn mirror on Github and add my changes there.

You can install the gem using this command:

  $ gem sources -a # (you only have to do this once)
  $ gem install romanbsd-gsl

8 Responses to “Non-negative Matrix Factorization for Ruby”

  1. v01d Says:

    I was looking for some other work on wrapping GSL with Ruby on GitHub and I found yours.
    I just wanted to let you know that I’m trying to create a good wrapper for GSL using RubyFFI, in case you’re interested in it.
    I’m currently wrapping Matrix so maybe you should wait a little, but you could eventually submit your work on NMF (which I know nothing about =b) as an extension to my wrapper (it should be really easy using FFI, specially if you already have the C code).



    Roman Reply:

    What is motivation behind this effort? Is it that you’d like to use GSL with JRuby?
    Because with MRI the performance of C version is better than of FFI…


  2. v01d Says:

    Since GSL is really big and creating a wrapper gets quite complex (eventually, you have a ton of C code and it is impossible to maintain/extend), I thought that FFI could help in this aspect.
    Regarding the performance, I’m not really sure if there’s really an important difference, although I’ll create some benchmarks when I have more code wrapped.
    There are some other objectives I pursue with this wrapper, you can read them here:



  3. charles Says:


    Do you have some examples of the ruby interface to the NMF code?

    How to do you choose the seed values?
    Which algorithm did you implement?
    How large of a system can you solve?




    Roman Reply:


    The seed values are picked randomly in the min..max interval.
    The algorithm is the one that circulated in some pdf, I don’t remember the name of the authors. You can see the implementation here:

    I know that it solves a system of thousands of rows.


  4. charles Says:

    Just curious as to the status of this (and the FFI wrapper)
    I am trying to get this to install on Mac OS X using ruby 1.9.2
    I find the following error (which I assume is because I am in ruby 1.9.2 and not 1.8.6/7):

    It would be great to get this working under ruby 1.9.2
    Any idea how hard that would be?

    [I can't get the FFi wrapper version of ruby gsl to install either]

    gcc -I. -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/x86_64-darwin10.4.0 -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/ruby/backward -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1 -I. -DHAVE_NARRAY_H -I/Users/charlesmartin/.rvm/gems/ruby-1.9.2-p0/gems/narray- -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.4.0 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -fno-common -Wall -I../include -I/usr/local/include -o array.o -c array.c
    In file included from ../include/rb_gsl_array.h:16,
    from array.c:15:
    /Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/ruby/backward/rubyio.h:2:2: warning: #warning use “ruby/io.h” instead of “rubyio.h”
    array.c: In function ‘carray_set_from_rarray’:
    array.c:214: error: ‘struct RArray’ has no member named ‘len’
    array.c: In function ‘Init_gsl_array’:
    array.c:656: warning: implicit declaration of function ‘Init_gsl_matrix_nmf’
    make: *** [array.o] Error 1


  5. sound proof paint Says:

    So any unwelcome sound that reaches the ear is usually considered undesirable and given the
    label of “noise”. Like Digital Performer, it also performs best when
    teamed with proprietary hardware. Once they are aware
    of the problem, they may start to walk around their apartment
    in stocking feet.


  6. News Jan Bwerkowitz Says:

    When I originally commented I clicked the “Notify me when new comments are added” checkbox
    and now each time a comment is added I get several emails with the same comment.

    Is there any way you can remove people from that service?
    Bless you!


Leave a Reply