measurable 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.travis.yml +8 -0
- data/Gemfile +2 -1
- data/README.md +8 -6
- data/Rakefile +18 -12
- data/lib/measurable.rb +1 -0
- data/lib/measurable/cosine.rb +27 -4
- data/lib/measurable/hamming.rb +4 -2
- data/lib/measurable/jaccard.rb +10 -17
- data/lib/measurable/levenshtein.rb +58 -0
- data/lib/measurable/version.rb +2 -2
- data/measurable.gemspec +4 -2
- data/spec/cosine_spec.rb +53 -21
- data/spec/jaccard_spec.rb +3 -3
- data/spec/levenshtein_spec.rb +55 -0
- data/spec/tanimoto_spec.rb +2 -2
- metadata +49 -18
- data/Gemfile.lock +0 -27
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: aaf11caa585477217fa9724f7f8c8a794490194f
         | 
| 4 | 
            +
              data.tar.gz: 2e802d508407c4b656501c9a18af5130ae488979
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 971e40facf06a090f515d1cd450006ce370d6ff460c8a9af65c9791ced5fddba58defdaff70c51cd9ce202ce712c7e0074b387507155de2c93250725cd3547f0
         | 
| 7 | 
            +
              data.tar.gz: 7f2714aeca034f418567b555c0fd5f99bcfce34d2ab73d595a2d4aa5d6cb5abdd620e2502182ce8537d0d7c1dccdba4285dabe4f9877e175a4973ae1ff155126
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,5 +1,8 @@ | |
| 1 1 | 
             
            # Measurable
         | 
| 2 2 |  | 
| 3 | 
            +
            [](https://travis-ci.org/agarie/measurable)
         | 
| 4 | 
            +
            [](https://codeclimate.com/github/agarie/measurable)
         | 
| 5 | 
            +
             | 
| 3 6 | 
             
            A gem to test what metric is best for certain kinds of datasets in machine learning.
         | 
| 4 7 |  | 
| 5 8 | 
             
            Besides the `Array` class, I also want to support `NVector` (from [NMatrix](http://github.com/sciruby/nmatrix)).
         | 
| @@ -30,6 +33,7 @@ The following are the similarity measures supported at the moment: | |
| 30 33 | 
             
            - Minkowski (Cityblock or Manhattan) distance
         | 
| 31 34 | 
             
            - Chebyshev distance
         | 
| 32 35 | 
             
            - Hamming distance
         | 
| 36 | 
            +
            - [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance)
         | 
| 33 37 |  | 
| 34 38 | 
             
            These still need to be implemented:
         | 
| 35 39 |  | 
| @@ -49,8 +53,8 @@ The API I intend to support is something like this: | |
| 49 53 | 
             
            ```ruby
         | 
| 50 54 | 
             
            require "measurable"
         | 
| 51 55 |  | 
| 52 | 
            -
            u =  | 
| 53 | 
            -
            v =  | 
| 56 | 
            +
            u = NMatrix.ones([2, 1])
         | 
| 57 | 
            +
            v = NMatrix.zeros([2, 1])
         | 
| 54 58 | 
             
            w = [1, 0]
         | 
| 55 59 | 
             
            x = [2, 2]
         | 
| 56 60 |  | 
| @@ -68,11 +72,9 @@ Measurable.euclidean_squared([3, 4]) # => 25 | |
| 68 72 | 
             
            `RDoc` syntax is used to document the project. To build it locally, you'll need to install the [Fivefish generator](https://github.com/ged/rdoc-generator-fivefish) (`gem install rdoc-generator-fivefish`) and run the following command:
         | 
| 69 73 |  | 
| 70 74 | 
             
            ```bash
         | 
| 71 | 
            -
            rdoc | 
| 75 | 
            +
            rake rdoc
         | 
| 72 76 | 
             
            ```
         | 
| 73 77 |  | 
| 74 | 
            -
            I want to be able to use a Rake task to generate the documentation, thus allowing me to forget the specific command. However, there's a bug in `RDoc::Task` in which [custom generators (like Fivefish) can't be used](https://github.com/rdoc/rdoc/issues/246).
         | 
| 75 | 
            -
             | 
| 76 78 | 
             
            If there's something wrong with an explanation or if there's information missing, please open an issue or send a pull request.
         | 
| 77 79 |  | 
| 78 80 | 
             
            ## License
         | 
| @@ -82,4 +84,4 @@ See LICENSE for details. | |
| 82 84 | 
             
            The original `distance_measures` gem is copyrighted by [@reddavis][reddavis].
         | 
| 83 85 |  | 
| 84 86 | 
             
            [maxmin]: http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=05156398
         | 
| 85 | 
            -
            [reddavis]: (https://github.com/reddavis)
         | 
| 87 | 
            +
            [reddavis]: (https://github.com/reddavis)
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            require 'rake'
         | 
| 2 2 | 
             
            require 'bundler/gem_tasks'
         | 
| 3 3 | 
             
            require "rspec/core/rake_task"
         | 
| 4 | 
            -
             | 
| 4 | 
            +
            require 'rdoc/task'
         | 
| 5 5 |  | 
| 6 6 | 
             
            # Setup the necessary gems, specified in the gemspec.
         | 
| 7 7 | 
             
            require 'bundler'
         | 
| @@ -13,20 +13,26 @@ rescue Bundler::BundlerError => e | |
| 13 13 | 
             
              exit e.status_code
         | 
| 14 14 | 
             
            end
         | 
| 15 15 |  | 
| 16 | 
            +
            task :default => [:spec]
         | 
| 17 | 
            +
             | 
| 16 18 | 
             
            # Run all the specs.
         | 
| 17 19 | 
             
            RSpec::Core::RakeTask.new(:spec)
         | 
| 18 20 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 21 | 
            +
            RDoc::Task.new do |rdoc|
         | 
| 22 | 
            +
              rdoc.main = "README.md"
         | 
| 23 | 
            +
              rdoc.rdoc_files.include("README.md", "LICENSE", "lib")
         | 
| 24 | 
            +
              rdoc.generator = "fivefish"
         | 
| 25 | 
            +
              rdoc.external = true
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            desc "Open IRB with Measurable loaded."
         | 
| 29 | 
            +
            task :console do
         | 
| 30 | 
            +
              require 'irb'
         | 
| 31 | 
            +
              require 'irb/completion'
         | 
| 32 | 
            +
              require 'measurable'
         | 
| 33 | 
            +
              ARGV.clear
         | 
| 34 | 
            +
              IRB.start
         | 
| 35 | 
            +
            end
         | 
| 30 36 |  | 
| 31 37 | 
             
            # Compile task.
         | 
| 32 38 | 
             
            # Rake::ExtensionTask.new do |ext|
         | 
    
        data/lib/measurable.rb
    CHANGED
    
    
    
        data/lib/measurable/cosine.rb
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            module Measurable
         | 
| 2 2 |  | 
| 3 3 | 
             
              # call-seq:
         | 
| 4 | 
            -
              #      | 
| 4 | 
            +
              #     cosine_similarity(u, v) -> Float
         | 
| 5 5 | 
             
              #
         | 
| 6 | 
            -
              # Calculate the similarity between the orientation of two vectors.
         | 
| 6 | 
            +
              # Calculate the cosine similarity between the orientation of two vectors.
         | 
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              # See: http://en.wikipedia.org/wiki/Cosine_similarity
         | 
| 9 9 | 
             
              #
         | 
| @@ -16,7 +16,7 @@ module Measurable | |
| 16 16 | 
             
              # * *Raises* :
         | 
| 17 17 | 
             
              #   - +ArgumentError+ -> The sizes of +u+ and +v+ don't match.
         | 
| 18 18 | 
             
              #
         | 
| 19 | 
            -
              def  | 
| 19 | 
            +
              def cosine_similarity(u, v)
         | 
| 20 20 | 
             
                # TODO: Change this to a more specific, custom-made exception.
         | 
| 21 21 | 
             
                raise ArgumentError if u.size != v.size
         | 
| 22 22 |  | 
| @@ -24,4 +24,27 @@ module Measurable | |
| 24 24 |  | 
| 25 25 | 
             
                dot_product / (euclidean(u) * euclidean(v))
         | 
| 26 26 | 
             
              end
         | 
| 27 | 
            -
             | 
| 27 | 
            +
             | 
| 28 | 
            +
              # call-seq:
         | 
| 29 | 
            +
              #     cosine_distance(u, v) -> Float
         | 
| 30 | 
            +
              #
         | 
| 31 | 
            +
              # Calculate the cosine distance between the orientation of two vectors.
         | 
| 32 | 
            +
              #
         | 
| 33 | 
            +
              # See: http://en.wikipedia.org/wiki/Cosine_similarity
         | 
| 34 | 
            +
              #
         | 
| 35 | 
            +
              # * *Arguments* :
         | 
| 36 | 
            +
              #   - +u+ -> An array of Numeric objects.
         | 
| 37 | 
            +
              #   - +v+ -> An array of Numeric objects.
         | 
| 38 | 
            +
              # * *Returns* :
         | 
| 39 | 
            +
              #   - The normalized dot product of +u+ and +v+, that is, the angle between
         | 
| 40 | 
            +
              #     them in the n-dimensional space.
         | 
| 41 | 
            +
              # * *Raises* :
         | 
| 42 | 
            +
              #   - +ArgumentError+ -> The sizes of +u+ and +v+ don't match.
         | 
| 43 | 
            +
              #
         | 
| 44 | 
            +
              def cosine_distance(u, v)
         | 
| 45 | 
            +
                # TODO: Change this to a more specific, custom-made exception.
         | 
| 46 | 
            +
                raise ArgumentError if u.size != v.size
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                1 - cosine_similarity(u, v)
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
    
        data/lib/measurable/hamming.rb
    CHANGED
    
    | @@ -3,9 +3,11 @@ module Measurable | |
| 3 3 | 
             
              # call-seq:
         | 
| 4 4 | 
             
              #     hamming(s1, s2) -> Integer
         | 
| 5 5 | 
             
              #
         | 
| 6 | 
            +
              # Count the number of different characters between strings +s1+ and +s2+,
         | 
| 7 | 
            +
              # that is, how many substitutions are necessary to change +s1+ into +s2+ and
         | 
| 8 | 
            +
              # vice-versa.
         | 
| 6 9 | 
             
              #
         | 
| 7 | 
            -
              #
         | 
| 8 | 
            -
              # See: http://en.wikipedia.org/wiki/Cosine_similarity
         | 
| 10 | 
            +
              # See: http://en.wikipedia.org/wiki/Hamming_distance
         | 
| 9 11 | 
             
              #
         | 
| 10 12 | 
             
              # * *Arguments* :
         | 
| 11 13 | 
             
              #   - +s1+ -> A String.
         | 
    
        data/lib/measurable/jaccard.rb
    CHANGED
    
    | @@ -10,15 +10,15 @@ module Measurable | |
| 10 10 | 
             
              # cardinality of set x.
         | 
| 11 11 | 
             
              #
         | 
| 12 12 | 
             
              # For example:
         | 
| 13 | 
            -
              #   jaccard_index([1, 0, 1], [1, 1, 1]) == 0. | 
| 13 | 
            +
              #   jaccard_index([1, 0, 1], [1, 1, 1]) == 0.5
         | 
| 14 14 | 
             
              #
         | 
| 15 | 
            -
              # Because |intersection| = |(1 | 
| 15 | 
            +
              # Because |intersection| = |(1)| = 1 and |union| = |(0, 1)| = 2.
         | 
| 16 16 | 
             
              #
         | 
| 17 17 | 
             
              # See: http://en.wikipedia.org/wiki/Jaccard_coefficient
         | 
| 18 18 | 
             
              #
         | 
| 19 19 | 
             
              # * *Arguments* :
         | 
| 20 | 
            -
              #   - +u+ -> Array | 
| 21 | 
            -
              #   - +v+ -> Array | 
| 20 | 
            +
              #   - +u+ -> Array.
         | 
| 21 | 
            +
              #   - +v+ -> Array.
         | 
| 22 22 | 
             
              # * *Returns* :
         | 
| 23 23 | 
             
              #   - Float value representing the Jaccard similarity coefficient between
         | 
| 24 24 | 
             
              #     +u+ and +v+.
         | 
| @@ -29,17 +29,10 @@ module Measurable | |
| 29 29 | 
             
                # TODO: Change this to a more specific, custom-made exception.
         | 
| 30 30 | 
             
                raise ArgumentError if u.size != v.size
         | 
| 31 31 |  | 
| 32 | 
            -
                intersection = u | 
| 33 | 
            -
             | 
| 34 | 
            -
                  elem[0] + elem[1] == 2 ? (acc + 1) : acc
         | 
| 35 | 
            -
                end
         | 
| 32 | 
            +
                intersection = u & v
         | 
| 33 | 
            +
                union = u | v
         | 
| 36 34 |  | 
| 37 | 
            -
                 | 
| 38 | 
            -
                  # One of u and v must have this element.
         | 
| 39 | 
            -
                  elem[0] + elem[1] >= 1 ? (acc + 1) : acc
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                intersection.to_f / union
         | 
| 35 | 
            +
                intersection.length.to_f / union.length
         | 
| 43 36 | 
             
              end
         | 
| 44 37 |  | 
| 45 38 | 
             
              # call-seq:
         | 
| @@ -56,8 +49,8 @@ module Measurable | |
| 56 49 | 
             
              #   - Triangular inequality: jaccard(u, v) <= jaccard(u, w) + jaccard(w, v)
         | 
| 57 50 | 
             
              #
         | 
| 58 51 | 
             
              # * *Arguments* :
         | 
| 59 | 
            -
              #   - +u+ -> Array | 
| 60 | 
            -
              #   - +v+ -> Array | 
| 52 | 
            +
              #   - +u+ -> Array.
         | 
| 53 | 
            +
              #   - +v+ -> Array.
         | 
| 61 54 | 
             
              # * *Returns* :
         | 
| 62 55 | 
             
              #   - Float value representing the dissimilarity between +u+ and +v+.
         | 
| 63 56 | 
             
              # * *Raises* :
         | 
| @@ -66,4 +59,4 @@ module Measurable | |
| 66 59 | 
             
              def jaccard(u, v)
         | 
| 67 60 | 
             
                1 - jaccard_index(u, v)
         | 
| 68 61 | 
             
              end
         | 
| 69 | 
            -
            end
         | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            module Measurable
         | 
| 2 | 
            +
              module Levenshtein
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                # call-seq:
         | 
| 5 | 
            +
                #     levenshtein(u, v) -> Integer
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                # Give the edit distance between two binary sequences +u+ and +v+ where each
         | 
| 8 | 
            +
                # edit (insertion, deletion, substitution) required to change on into the
         | 
| 9 | 
            +
                # other increments the total distance.
         | 
| 10 | 
            +
                #
         | 
| 11 | 
            +
                # For example:
         | 
| 12 | 
            +
                #   levenshtein('kitten', 'sitting') == 3
         | 
| 13 | 
            +
                #
         | 
| 14 | 
            +
                # Because
         | 
| 15 | 
            +
                # 1. kitten -> sitten (substitution "s" for "k")
         | 
| 16 | 
            +
                # 2. sitten -> sittin (substitution "i" for "e")
         | 
| 17 | 
            +
                # 3. sittin -> sitting (insertion of "g" at the end)
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # See: http://en.wikipedia.org/wiki/Levenshtein_distance
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # * *Arguments* :
         | 
| 22 | 
            +
                #   - +u+ -> Array or String.
         | 
| 23 | 
            +
                #   - +v+ -> Array or String.
         | 
| 24 | 
            +
                # * *Returns* :
         | 
| 25 | 
            +
                #   - Integer value representing the Levenshtein distance between
         | 
| 26 | 
            +
                #     +u+ and +v+.
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                def levenshtein(u, v)
         | 
| 29 | 
            +
                  return 0 if u == v
         | 
| 30 | 
            +
                  return u.size if v.size == 0
         | 
| 31 | 
            +
                  return v.size if u.size == 0
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  matrix = Array.new(u.size+1) { (0..v.size).to_a }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  if v.size < u.size
         | 
| 36 | 
            +
                    u, v = v, u
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  (1..u.size).each do |i|
         | 
| 40 | 
            +
                    (1..v.size).each do |j|
         | 
| 41 | 
            +
                      if u[i] == v[j]
         | 
| 42 | 
            +
                        matrix[i][j] = matrix[i-1][j-1]
         | 
| 43 | 
            +
                      else
         | 
| 44 | 
            +
                        matrix[i][j] = [
         | 
| 45 | 
            +
                          matrix[i-1][j] + 1,   # deletion
         | 
| 46 | 
            +
                          matrix[i][j-1] + 1,   # insertion
         | 
| 47 | 
            +
                          matrix[i-1][j-1] + 1, # substitution
         | 
| 48 | 
            +
                        ].min
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  matrix[u.size][v.size]
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              extend Measurable::Levenshtein
         | 
| 58 | 
            +
            end
         | 
    
        data/lib/measurable/version.rb
    CHANGED
    
    | @@ -1,3 +1,3 @@ | |
| 1 1 | 
             
            module Measurable
         | 
| 2 | 
            -
              VERSION = "0.0. | 
| 3 | 
            -
            end
         | 
| 2 | 
            +
              VERSION = "0.0.7" # :nodoc:
         | 
| 3 | 
            +
            end
         | 
    
        data/measurable.gemspec
    CHANGED
    
    | @@ -24,6 +24,8 @@ Gem::Specification.new do |gem| | |
| 24 24 | 
             
              gem.required_ruby_version = '>= 1.9.3'
         | 
| 25 25 |  | 
| 26 26 | 
             
              gem.add_development_dependency 'bundler'
         | 
| 27 | 
            -
              gem.add_development_dependency 'rake', '~>  | 
| 28 | 
            -
              gem.add_development_dependency ' | 
| 27 | 
            +
              gem.add_development_dependency 'rake', '~> 10.1'
         | 
| 28 | 
            +
              gem.add_development_dependency 'rdoc', '~> 4.1'
         | 
| 29 | 
            +
              gem.add_development_dependency 'rspec', '~> 2.1'
         | 
| 30 | 
            +
              gem.add_development_dependency 'rdoc-generator-fivefish'
         | 
| 29 31 | 
             
            end
         | 
    
        data/spec/cosine_spec.rb
    CHANGED
    
    | @@ -1,29 +1,61 @@ | |
| 1 | 
            -
            describe "Cosine | 
| 1 | 
            +
            describe "Cosine" do
         | 
| 2 2 |  | 
| 3 | 
            -
               | 
| 4 | 
            -
                 | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 3 | 
            +
              context "Similarity" do
         | 
| 4 | 
            +
                before :all do
         | 
| 5 | 
            +
                  @u = [1, 2]
         | 
| 6 | 
            +
                  @v = [2, 3]
         | 
| 7 | 
            +
                  @w = [4, 5]
         | 
| 8 | 
            +
                end
         | 
| 8 9 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 10 | 
            +
                it "accepts two arguments" do
         | 
| 11 | 
            +
                  expect { Measurable.cosine_similarity(@u, @v) }.to_not raise_error
         | 
| 12 | 
            +
                  expect { Measurable.cosine_similarity(@u, @v, @w) }.to raise_error(ArgumentError)
         | 
| 13 | 
            +
                end
         | 
| 13 14 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 15 | 
            +
                it "should be symmetric" do
         | 
| 16 | 
            +
                  x = Measurable.cosine_similarity(@u, @v)
         | 
| 17 | 
            +
                  y = Measurable.cosine_similarity(@v, @u)
         | 
| 17 18 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 19 | 
            +
                  x.should be_within(TOLERANCE).of(y)
         | 
| 20 | 
            +
                end
         | 
| 20 21 |  | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 22 | 
            +
                it "should return the correct value" do
         | 
| 23 | 
            +
                  x = Measurable.cosine_similarity(@u, @v)
         | 
| 24 | 
            +
                  x.should be_within(TOLERANCE).of(0.992277877)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it "shouldn't work with vectors of different length" do
         | 
| 28 | 
            +
                  expect { Measurable.cosine_similarity(@u, [1, 3, 5, 7]) }.to raise_error(ArgumentError)
         | 
| 29 | 
            +
                end
         | 
| 24 30 | 
             
              end
         | 
| 25 31 |  | 
| 26 | 
            -
               | 
| 27 | 
            -
                 | 
| 32 | 
            +
              context "Distance" do
         | 
| 33 | 
            +
                before :all do
         | 
| 34 | 
            +
                  @u = [1, 2]
         | 
| 35 | 
            +
                  @v = [2, 3]
         | 
| 36 | 
            +
                  @w = [4, 5]
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                it "accepts two arguments" do
         | 
| 40 | 
            +
                  expect { Measurable.cosine_distance(@u, @v) }.to_not raise_error
         | 
| 41 | 
            +
                  expect { Measurable.cosine_distance(@u, @v, @w) }.to raise_error(ArgumentError)
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it "should be symmetric" do
         | 
| 45 | 
            +
                  x = Measurable.cosine_distance(@u, @v)
         | 
| 46 | 
            +
                  y = Measurable.cosine_distance(@v, @u)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  x.should be_within(TOLERANCE).of(y)
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                it "should return the correct value" do
         | 
| 52 | 
            +
                  x = Measurable.cosine_distance(@u, @v)
         | 
| 53 | 
            +
                  # TODO: Use a real example.
         | 
| 54 | 
            +
                  x.should be_within(TOLERANCE).of(1.0 - 0.992277877)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                it "shouldn't work with vectors of different length" do
         | 
| 58 | 
            +
                  expect { Measurable.cosine_distance(@u, [1, 3, 5, 7]) }.to raise_error(ArgumentError)
         | 
| 59 | 
            +
                end
         | 
| 28 60 | 
             
              end
         | 
| 29 | 
            -
            end
         | 
| 61 | 
            +
            end
         | 
    
        data/spec/jaccard_spec.rb
    CHANGED
    
    | @@ -22,7 +22,7 @@ describe "Jaccard" do | |
| 22 22 | 
             
                it "should return the correct value" do
         | 
| 23 23 | 
             
                  x = Measurable.jaccard_index(@u, @v)
         | 
| 24 24 |  | 
| 25 | 
            -
                  x.should be_within(TOLERANCE).of( | 
| 25 | 
            +
                  x.should be_within(TOLERANCE).of(1.0 / 2.0)
         | 
| 26 26 | 
             
                end
         | 
| 27 27 |  | 
| 28 28 | 
             
                it "shouldn't work with vectors of different length" do
         | 
| @@ -52,11 +52,11 @@ describe "Jaccard" do | |
| 52 52 | 
             
                it "should return the correct value" do
         | 
| 53 53 | 
             
                  x = Measurable.jaccard(@u, @v)
         | 
| 54 54 |  | 
| 55 | 
            -
                  x.should be_within(TOLERANCE).of(1.0 /  | 
| 55 | 
            +
                  x.should be_within(TOLERANCE).of(1.0 / 2.0)
         | 
| 56 56 | 
             
                end
         | 
| 57 57 |  | 
| 58 58 | 
             
                it "shouldn't work with vectors of different length" do
         | 
| 59 59 | 
             
                  expect { Measurable.jaccard(@u, [1, 2, 3, 4]) }.to raise_error(ArgumentError)
         | 
| 60 60 | 
             
                end
         | 
| 61 61 | 
             
              end
         | 
| 62 | 
            -
            end
         | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            describe Measurable::Levenshtein do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              context "strings" do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                it "handles empty" do
         | 
| 6 | 
            +
                  Measurable.levenshtein("", "").should == 0
         | 
| 7 | 
            +
                  Measurable.levenshtein("", "abcd").should == 4
         | 
| 8 | 
            +
                  Measurable.levenshtein("abcd", "").should == 4
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                it "should not count equality" do
         | 
| 12 | 
            +
                  Measurable.levenshtein("aa", "aa").should == 0
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                it "should count deletion" do
         | 
| 16 | 
            +
                  Measurable.levenshtein("ab", "a").should == 1
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                it "should count insertion" do
         | 
| 20 | 
            +
                  Measurable.levenshtein("ab", "abc").should == 1
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                it "should count substitution" do
         | 
| 24 | 
            +
                  Measurable.levenshtein("aa", "ab").should == 1
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              context "arrays" do
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                it "handles empty" do
         | 
| 32 | 
            +
                  Measurable.levenshtein([], []).should == 0
         | 
| 33 | 
            +
                  Measurable.levenshtein([], %w[ a b c d ]).should == 4
         | 
| 34 | 
            +
                  Measurable.levenshtein(%w[ a b c d ], []).should == 4
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                it "should not count equality" do
         | 
| 38 | 
            +
                  Measurable.levenshtein(%w[ a ], %w[ a ]).should == 0
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                it "should count deletion" do
         | 
| 42 | 
            +
                  Measurable.levenshtein(%w[ a b ], %w[ a ]).should == 1
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                it "should count insertion" do
         | 
| 46 | 
            +
                  Measurable.levenshtein(%w[ a b ], %w[ a b c ]).should == 1
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                it "should count substitution" do
         | 
| 50 | 
            +
                  Measurable.levenshtein(%w[ a a ], %w[ a b ]).should == 1
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            end
         | 
    
        data/spec/tanimoto_spec.rb
    CHANGED
    
    | @@ -21,10 +21,10 @@ describe "Tanimoto distance" do | |
| 21 21 | 
             
              it "should return the correct value" do
         | 
| 22 22 | 
             
                x = Measurable.tanimoto(@u, @v)
         | 
| 23 23 |  | 
| 24 | 
            -
                x.should be_within(TOLERANCE).of(-Math.log2( | 
| 24 | 
            +
                x.should be_within(TOLERANCE).of(-Math.log2(1.0 / 2.0))
         | 
| 25 25 | 
             
              end
         | 
| 26 26 |  | 
| 27 27 | 
             
              it "shouldn't work with vectors of different length" do
         | 
| 28 28 | 
             
                expect { Measurable.tanimoto(@u, [1, 3, 5, 7]) }.to raise_error(ArgumentError)
         | 
| 29 29 | 
             
              end
         | 
| 30 | 
            -
            end
         | 
| 30 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,67 +1,95 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: measurable
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.7
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Carlos Agarie
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2014-04-14 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - -  | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 19 | 
             
                    version: '0'
         | 
| 20 20 | 
             
              type: :development
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - -  | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: rake
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 | 
            -
                - - ~>
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: ' | 
| 33 | 
            +
                    version: '10.1'
         | 
| 34 34 | 
             
              type: :development
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 | 
            -
                - - ~>
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version: ' | 
| 40 | 
            +
                    version: '10.1'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rdoc
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '4.1'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '4.1'
         | 
| 41 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 56 | 
             
              name: rspec
         | 
| 43 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 58 | 
             
                requirements:
         | 
| 45 | 
            -
                - - ~>
         | 
| 59 | 
            +
                - - "~>"
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '2.1'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - "~>"
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '2.1'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: rdoc-generator-fivefish
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 46 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            -
                    version:  | 
| 75 | 
            +
                    version: '0'
         | 
| 48 76 | 
             
              type: :development
         | 
| 49 77 | 
             
              prerelease: false
         | 
| 50 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 79 | 
             
                requirements:
         | 
| 52 | 
            -
                - -  | 
| 80 | 
            +
                - - ">="
         | 
| 53 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            -
                    version:  | 
| 82 | 
            +
                    version: '0'
         | 
| 55 83 | 
             
            description: A Ruby gem with a lot of distance measures for your projects.
         | 
| 56 84 | 
             
            email: carlos.agarie@gmail.com
         | 
| 57 85 | 
             
            executables: []
         | 
| 58 86 | 
             
            extensions: []
         | 
| 59 87 | 
             
            extra_rdoc_files: []
         | 
| 60 88 | 
             
            files:
         | 
| 61 | 
            -
            - .gitignore
         | 
| 62 | 
            -
            - .rspec
         | 
| 89 | 
            +
            - ".gitignore"
         | 
| 90 | 
            +
            - ".rspec"
         | 
| 91 | 
            +
            - ".travis.yml"
         | 
| 63 92 | 
             
            - Gemfile
         | 
| 64 | 
            -
            - Gemfile.lock
         | 
| 65 93 | 
             
            - LICENSE
         | 
| 66 94 | 
             
            - README.md
         | 
| 67 95 | 
             
            - Rakefile
         | 
| @@ -72,6 +100,7 @@ files: | |
| 72 100 | 
             
            - lib/measurable/hamming.rb
         | 
| 73 101 | 
             
            - lib/measurable/haversine.rb
         | 
| 74 102 | 
             
            - lib/measurable/jaccard.rb
         | 
| 103 | 
            +
            - lib/measurable/levenshtein.rb
         | 
| 75 104 | 
             
            - lib/measurable/maxmin.rb
         | 
| 76 105 | 
             
            - lib/measurable/minkowski.rb
         | 
| 77 106 | 
             
            - lib/measurable/tanimoto.rb
         | 
| @@ -83,6 +112,7 @@ files: | |
| 83 112 | 
             
            - spec/hamming_spec.rb
         | 
| 84 113 | 
             
            - spec/haversine_spec.rb
         | 
| 85 114 | 
             
            - spec/jaccard_spec.rb
         | 
| 115 | 
            +
            - spec/levenshtein_spec.rb
         | 
| 86 116 | 
             
            - spec/maxmin_spec.rb
         | 
| 87 117 | 
             
            - spec/minkowski_spec.rb
         | 
| 88 118 | 
             
            - spec/spec_helper.rb
         | 
| @@ -97,17 +127,17 @@ require_paths: | |
| 97 127 | 
             
            - lib
         | 
| 98 128 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 99 129 | 
             
              requirements:
         | 
| 100 | 
            -
              - -  | 
| 130 | 
            +
              - - ">="
         | 
| 101 131 | 
             
                - !ruby/object:Gem::Version
         | 
| 102 132 | 
             
                  version: 1.9.3
         | 
| 103 133 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 104 134 | 
             
              requirements:
         | 
| 105 | 
            -
              - -  | 
| 135 | 
            +
              - - ">="
         | 
| 106 136 | 
             
                - !ruby/object:Gem::Version
         | 
| 107 137 | 
             
                  version: '0'
         | 
| 108 138 | 
             
            requirements: []
         | 
| 109 139 | 
             
            rubyforge_project: 
         | 
| 110 | 
            -
            rubygems_version: 2. | 
| 140 | 
            +
            rubygems_version: 2.2.2
         | 
| 111 141 | 
             
            signing_key: 
         | 
| 112 142 | 
             
            specification_version: 4
         | 
| 113 143 | 
             
            summary: A Ruby gem with a lot of distance measures for your projects.
         | 
| @@ -118,6 +148,7 @@ test_files: | |
| 118 148 | 
             
            - spec/hamming_spec.rb
         | 
| 119 149 | 
             
            - spec/haversine_spec.rb
         | 
| 120 150 | 
             
            - spec/jaccard_spec.rb
         | 
| 151 | 
            +
            - spec/levenshtein_spec.rb
         | 
| 121 152 | 
             
            - spec/maxmin_spec.rb
         | 
| 122 153 | 
             
            - spec/minkowski_spec.rb
         | 
| 123 154 | 
             
            - spec/spec_helper.rb
         | 
    
        data/Gemfile.lock
    DELETED
    
    | @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            PATH
         | 
| 2 | 
            -
              remote: .
         | 
| 3 | 
            -
              specs:
         | 
| 4 | 
            -
                measurable (0.0.6)
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            GEM
         | 
| 7 | 
            -
              remote: http://rubygems.org/
         | 
| 8 | 
            -
              specs:
         | 
| 9 | 
            -
                diff-lcs (1.1.3)
         | 
| 10 | 
            -
                rake (0.9.6)
         | 
| 11 | 
            -
                rspec (2.9.0)
         | 
| 12 | 
            -
                  rspec-core (~> 2.9.0)
         | 
| 13 | 
            -
                  rspec-expectations (~> 2.9.0)
         | 
| 14 | 
            -
                  rspec-mocks (~> 2.9.0)
         | 
| 15 | 
            -
                rspec-core (2.9.0)
         | 
| 16 | 
            -
                rspec-expectations (2.9.1)
         | 
| 17 | 
            -
                  diff-lcs (~> 1.1.3)
         | 
| 18 | 
            -
                rspec-mocks (2.9.0)
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            PLATFORMS
         | 
| 21 | 
            -
              ruby
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            DEPENDENCIES
         | 
| 24 | 
            -
              bundler
         | 
| 25 | 
            -
              measurable!
         | 
| 26 | 
            -
              rake (~> 0.9)
         | 
| 27 | 
            -
              rspec (~> 2.9.0)
         |