LoginSignup
0
0

More than 5 years have passed since last update.

ruby 度数分布表

Last updated at Posted at 2017-08-21

度数分布表

rubyの勉強のために度数分布表を作ってみた。もっと短く賢く書きたい。。泣
誰かよりよい書き方、きれいな書き方などがあれば教えてくださいませ。

freq_dist.rb
  1 init_seed = 12345
  2 max_value = 16.00
  3 init_value = 10.0
  4 class_interval_width=0.9
  5 
  6 total = 50000.0
  7 
  8 # sample
  9 prng1 = Random.new(init_seed)
 10 sample = Array.new(total){(prng1.rand(9.4...20.1))}
 11 
 12 class_interval = init_value.step(max_value, class_interval_width).map{|i| i}
 13 
 14 frequency = Array.new(class_interval.size, 0)
 15 for num in sample do
 16   if class_interval[0] <= num && num < class_interval[-1]+class_interval_width
 17     b = class_interval.map{|i| i <= num ? num-i : max_value }
 18     class_num = b.each_with_index.map{|v, i| v == b.min ? i : nil}.compact.min
 19     frequency[class_num] += 1
 20   end
 21 end
 22 relative_frequency = frequency.map{|i| (i / sample.size.to_f) }
 23 
 24 cumulative_distribution_function = Array.new(class_interval.size, 0)
 25 cumulative_distribution_frequency = Array.new(class_interval.size, 0)
 26 for num in 0...class_interval.size do
 27   if num == 0
 28     cumulative_distribution_function[num] = frequency[num]
 29     cumulative_distribution_frequency[num] = relative_frequency[num]
 30   else
 31     cumulative_distribution_function[num] += cumulative_distribution_function[num-1]+frequency[num]
 32     cumulative_distribution_frequency[num] += cumulative_distribution_frequency[num-1]+relative_frequency    [num]
 33   end
 34 end
 35 
 36 printf("%s\t%s\t%s\t%s\t%s\n","階級","度数","相対度数","累積度数","累積相対度数")
 37 for num in 0...class_interval.size
 38   printf("%05.02f~%05.02f\t%02d\t%.02f\t%05d\t%.02f\n",class_interval[num],class_interval[num]+class_inte    rval_width,frequency[num],relative_frequency[num],cumulative_distribution_function[num],cumulative_distri    bution_frequency[num])
 39 end
$ ruby freq_dist.rb 
階級  度数  相対度数    累積度数    累積相対度数
10.00~10.90 4229    0.08    04229   0.08
10.90~11.80 4256    0.09    08485   0.17
11.80~12.70 4108    0.08    12593   0.25
12.70~13.60 4244    0.08    16837   0.34
13.60~14.50 4235    0.08    21072   0.42
14.50~15.40 4141    0.08    25213   0.50
15.40~16.30 4172    0.08    29385   0.59

スタージスの式を追加

freq_dist2.rb
  1 include Math
  2 
  3 init_seed = 12345
  4 
  5 # sample
  6 n = 100.0
  7 prng1 = Random.new(init_seed)
  8 sample = Array.new(n){(prng1.rand(300...400).round(2))}
  9 total = sample.size
 10 
 11 init_value = sample.min.to_f
 12 max_value = sample.max.to_f
 13 
 14 sturges = 1 + (log10(total.to_f) / log10(2)).round
 15 class_interval_width = ((max_value - init_value)/sturges).ceil(2)
 16 class_interval = init_value.step(max_value, class_interval_width).map{|i| i}
 17 
 18 frequency = Array.new(class_interval.size, 0)
 19 for num in sample do
 20   if class_interval[0] <= num && num < class_interval[-1]+class_interval_width
 21     b = class_interval.map{|i| i <= num ? num-i : max_value }
 22     class_num = b.each_with_index.map{|v, i| v == b.min ? i : nil}.compact.min
 23     frequency[class_num] += 1
 24   end
 25 end
 26 relative_frequency = frequency.map{|i| (i / total.to_f) }
 27 
 28 cumulative_distribution_function = Array.new(class_interval.size, 0)
 29 cumulative_distribution_frequency = Array.new(class_interval.size, 0)
 30 for num in 0...class_interval.size do
 31   if num == 0
 32     cumulative_distribution_function[num] = frequency[num]
 33     cumulative_distribution_frequency[num] = relative_frequency[num]
 34   else
 35     cumulative_distribution_function[num] += cumulative_distribution_function[num-1]+frequency[num]
 36     cumulative_distribution_frequency[num] += cumulative_distribution_frequency[num-1]+relative_frequency[num    ]
 37   end
 38 end
 39 
 40 p "-----"*10
 41 printf("%s\t%s\t%s\t%s\t%s\n","階級","度数","相対度数","累積度数","累積相対度数")
 42 p "-----"*10
 43 for num in 0...class_interval.size
 44   printf("%05.02f~%05.02f\t%02d\t%.02f\t%05d\t%.02f\n",class_interval[num],class_interval[num]+class_interval    _width,frequency[num],relative_frequency[num],cumulative_distribution_function[num],cumulative_distribution_f    requency[num])
 45 end
 46 p "-----"*10
 47 
 48 total = sample.inject{|result, i| result + i}
 49 ave = total/n
 50 median = sample.size % 2 == 0 ? sample[sample.size/2 - 1, 2].inject(:+) / 2.0 : sample[sample.size/2]
 51 mode = sample.uniq.sort_by{|x| sample.count x }.reverse[0]
 52 
 53 printf("最小値:\t\t%f\n",init_value)
 54 printf("最大値:\t\t%f\n",max_value)
 55 printf("総計値:\t\t%f\n",total)
 56 printf("平均値:\t\t%f\n",ave)
 57 printf("中央値:\t\t%f\n",median)
 58 printf("最頻値:\t\t%f\n",mode)
$ ruby freq_dist2.rb 
"--------------------------------------------------"
階級  度数  相対度数    累積度数    累積相対度数
"--------------------------------------------------"
300.00~312.38   18  0.18    00018   0.18
312.38~324.76   11  0.11    00029   0.29
324.76~337.14   13  0.13    00042   0.42
337.14~349.52   10  0.10    00052   0.52
349.52~361.90   10  0.10    00062   0.62
361.90~374.28   14  0.14    00076   0.76
374.28~386.66   13  0.13    00089   0.89
386.66~399.04   11  0.11    00100   1.00
"--------------------------------------------------"
最小値:      300.000000
最大値:      399.000000
総計値:      34721.000000
平均値:      347.210000
中央値:      353.500000
最頻値:      305.000000
0
0
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0