J'ai plusieurs enregistrements avec un attribut donné, et je veux trouver l'écart type.
Comment dois-je faire?
J'ai plusieurs enregistrements avec un attribut donné, et je veux trouver l'écart type.
Comment dois-je faire?
module Enumerable
def sum
self.inject(0){|accum, i| accum + i }
end
def mean
self.sum/self.length.to_f
end
def sample_variance
m = self.mean
sum = self.inject(0){|accum, i| accum +(i-m)**2 }
sum/(self.length - 1).to_f
end
def standard_deviation
return Math.sqrt(self.sample_variance)
end
end
Tester:
a = [ 20, 23, 23, 24, 25, 22, 12, 21, 29 ]
a.standard_deviation
# => 4.594682917363407
fixation "sample_variance" merci à Dave Sag
Il semble que Angela peut avoir envie d'une bibliothèque existante. Après avoir joué avec statsample, array-statisics, et quelques autres, je vous recommande la descriptive_statistics gem si vous êtes en essayant d'éviter de réinventer la roue.
gem install descriptive_statistics
$ irb
1.9.2p290 :001 > require 'descriptive_statistics'
=> true
1.9.2p290 :002 > samples = [1, 2, 2.2, 2.3, 4, 5]
=> [1, 2, 2.2, 2.3, 4, 5]
1.9.2p290 :003 > samples.sum
=> 16.5
1.9.2p290 :004 > samples.mean
=> 2.75
1.9.2p290 :005 > samples.variance
=> 1.7924999999999998
1.9.2p290 :006 > samples.standard_deviation
=> 1.3388427838995882
Je ne peux pas parler pour elle de statistique de l'exactitude, ou de votre confort avec le singe de correction Énumérable; mais il est facile à utiliser et facile à contribuer.
La réponse donnée ci-dessus est élégant, mais a une légère erreur. N'étant pas des stats de la tête moi-même je m'assis et lire en détail un certain nombre de sites web et trouvé celui-ci a donné la plus compréhensible explication de comment calculer un écart-type. http://sonia.hubpages.com/hub/stddev
L'erreur dans la réponse ci-dessus est dans l' sample_variance
méthode.
Voici ma version corrigée, avec une simple unité de test qui montre que cela fonctionne.
en ./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
en ./test
de l'utilisation des nombres dérivés à partir d'une simple feuille de calcul.
#!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
Je ne suis pas un grand fan de l'ajout de méthodes d' Enumerable
car il pourrait y avoir des effets secondaires indésirables. Il donne également des méthodes de vraiment spécifique à un tableau de nombres à toute classe héritant de Enumerable
, ce qui n'a pas de sens dans la plupart des cas.
Tout cela est très bien pour des tests, des scripts ou des petites applis, c'est risqué pour des applications plus importantes, alors voici une alternative basée sur @tolitius réponse qui était déjà parfait. C'est plus pour les référence qu'autre chose:
module MyApp::Maths
def self.sum(a)
a.inject(0){ |accum, i| accum + i }
end
def self.mean(a)
sum(a) / a.length.to_f
end
def self.sample_variance(a)
m = mean(a)
sum = a.inject(0){ |accum, i| accum + (i - m) ** 2 }
sum / (a.length - 1).to_f
end
def self.standard_deviation(a)
Math.sqrt(sample_variance(a))
end
end
Et puis vous l'utilisez en tant que tel:
2.0.0p353 > MyApp::Maths.standard_deviation([1,2,3,4,5])
=> 1.5811388300841898
2.0.0p353 :007 > a = [ 20, 23, 23, 24, 25, 22, 12, 21, 29 ]
=> [20, 23, 23, 24, 25, 22, 12, 21, 29]
2.0.0p353 :008 > MyApp::Maths.standard_deviation(a)
=> 4.594682917363407
2.0.0p353 :043 > MyApp::Maths.standard_deviation([1,2,2.2,2.3,4,5])
=> 1.466628787389638
Le comportement est le même, mais il évite les frais généraux et les risques d'ajouter des méthodes à l' Enumerable
.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.