How can I do standard deviation in Ruby?

后端 未结 9 1446
一个人的身影
一个人的身影 2021-01-30 15:45

I have several records with a given attribute, and I want to find the standard deviation.

How do I do that?

9条回答
  •  梦如初夏
    2021-01-30 16:51

    The answer given above is elegant but has a slight error in it. Not being a stats head myself I sat up and read in detail a number of websites and found this one gave the most comprehensible explanation of how to derive a standard deviation. http://sonia.hubpages.com/hub/stddev

    The error in the answer above is in the sample_variance method.

    Here is my corrected version, along with a simple unit test that shows it works.

    in ./lib/enumerable/standard_deviation.rb

    #!usr/bin/ruby
    
    module Enumerable
    
      def sum
        return self.inject(0){|accum, i| accum + i }
      end
    
      def mean
        return self.sum / self.length.to_f
      end
    
      def sample_variance
        m = self.mean
        sum = self.inject(0){|accum, i| accum + (i - m) ** 2 }
        return sum / (self.length - 1).to_f
      end
    
      def standard_deviation
        return Math.sqrt(self.sample_variance)
      end
    
    end
    

    in ./test using numbers derived from a simple spreadsheet.

    Screen Snapshot of a Numbers spreadsheet with example data

    #!usr/bin/ruby
    
    require 'enumerable/standard_deviation'
    
    class StandardDeviationTest < Test::Unit::TestCase
    
      THE_NUMBERS = [1, 2, 2.2, 2.3, 4, 5]
    
      def test_sum
        expected = 16.5
        result = THE_NUMBERS.sum
        assert result == expected, "expected #{expected} but got #{result}"
      end
    
      def test_mean
        expected = 2.75
        result = THE_NUMBERS.mean
        assert result == expected, "expected #{expected} but got #{result}"
      end
    
      def test_sample_variance
        expected = 2.151
        result = THE_NUMBERS.sample_variance
        assert result == expected, "expected #{expected} but got #{result}"
      end
    
      def test_standard_deviation
        expected = 1.4666287874
        result = THE_NUMBERS.standard_deviation
        assert result.round(10) == expected, "expected #{expected} but got #{result}"
      end
    
    end
    

提交回复
热议问题