Skip to content

Instantly share code, notes, and snippets.

@henrygarner
Created February 1, 2011 12:04
Show Gist options
  • Save henrygarner/805773 to your computer and use it in GitHub Desktop.
Save henrygarner/805773 to your computer and use it in GitHub Desktop.
A simple Ruby demonstration of Ted Dunning's log-likelihood statistical measure, via Paul Rayson http://ucrel.lancs.ac.uk/llwizard.html
require 'matrix'
module LLR
def self.calculate(m)
2 * (m.to_a.flatten.h - m.row_vectors.map(&:sum).h - m.column_vectors.map(&:sum).h)
end
def sum
to_a.inject(nil) { |sum, x| x = yield(x) if block_given?; sum ? sum + x : x }
end
def h
total = sum.to_f
sum { |x| x.zero? ? 0 : x * Math.log(x / total) }
end
end
[Vector, Array].each { |klass| klass.send :include, LLR }
require 'rubygems'
require 'rspec'
require 'matrix'
require 'llr.rb'
describe LLR do
it "should calculate the correct LLR" do
llr = LLR.calculate Matrix[[1,2],[3,4]]
llr.should be_within(1e-8).of(0.08043486)
llr = LLR.calculate Matrix[[1,0],[0,1]]
llr.should be_within(1e-6).of(2.772589)
llr = LLR.calculate Matrix[[10,0],[0,10]]
llr.should be_within(1e-5).of(27.72589)
llr = LLR.calculate Matrix[[2,0],[1,10000]]
llr.should be_within(1e-5).of(34.25049)
llr = LLR.calculate Matrix[[2,8],[1,10000]]
llr.should be_within(1e-5).of(24.24724)
end
end
@henrygarner
Copy link
Author

Below is the RSpec test I wrote to check the results against your vectors. I'm pleased to say that all assertions pass.

The initial gist does not generate the same results at all, although it seems to be a correct implementation of the formula at http://ucrel.lancs.ac.uk/llwizard.html

require 'rubygems'
require 'rspec'
require 'matrix'
require 'llr.rb'

describe LLR do
  it "should calculate the correct LLR" do

    llr = LLR.calculate Matrix[[1,2],[3,4]]
    llr.should be_within(1e-8).of(0.08043486)

    llr = LLR.calculate Matrix[[1,0],[0,1]]
    llr.should be_within(1e-6).of(2.772589)

    llr = LLR.calculate Matrix[[10,0],[0,10]]
    llr.should be_within(1e-5).of(27.72589)

    llr = LLR.calculate Matrix[[2,0],[1,10000]]
    llr.should be_within(1e-5).of(34.25049)

    llr = LLR.calculate Matrix[[2,8],[1,10000]]
    llr.should be_within(1e-5).of(24.24724)

  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment