Module: NormDist

Defined in:
lib/norm_dist.rb,
lib/norm_dist/version.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.chi_inv(f, p, max: 10, step: 1e-4) ⇒ Object

両側



147
148
149
150
151
# File 'lib/norm_dist.rb', line 147

def chi_inv(f, p, max:10, step: 1e-4)
  right = chi_inv_r(f, p, max: max, step: step)
  left = chi_inv_l(f, p, min: 0, step: step)
  return [right, left]
end

.chi_inv_l(f, p, min: 0, step: 1e-4) ⇒ Object

左側



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/norm_dist.rb', line 133

def chi_inv_l(f, p, min: 0, step: 1e-4)
  x = min
  
  # 最初のwhileを通すよう初期値設定
  chi = -0.1
  
  while chi < 1 - p
    chi = Distribution::ChiSquare.cdf(x, f)
    x += step
  end
  return x
end

.chi_inv_r(f, p, max: 10, step: 1e-4) ⇒ Object

右側



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/norm_dist.rb', line 119

def chi_inv_r(f, p, max: 10, step: 1e-4)
  x = max
  
  # 最初のwhileを通すよう初期値設定
  chi = 1.1
  
  while chi > p
    chi = Distribution::ChiSquare.cdf(x, f)
    x -= step
  end
  return x
end

.estimate(df, colname, n: 20, print_data: true) ⇒ Object

平均値の区間推定



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/norm_dist.rb', line 46

def estimate(df, colname, n: 20, print_data: true)
  # サンプリング
  samples = df.row[*(df.index.to_a.sample(n))]

  # 定数の計算
  m = samples[colname].mean
  v = samples[colname].variance
  sig = v ** 0.5

  # 信頼区間95%の推定
  area =  [m - 1.96 * sig / Math::sqrt(n), m + 1.96 * sig / Math::sqrt(n)]
  print_data && print(area)
  
  # 検証
  area_range = area[0]..area[1]
  true_ave = df[colname].mean
  correct = area_range.include?(true_ave) 
  
  print_data && print(correct ? " OK\n" : " NG\n")
  return correct
end

.normal_cdf(x, mu, sigma) ⇒ Object

多分、正規分布を標準化とか軒並み言ってるのは累積分布のことなんだろう。 なにしろ標準分布表の値のことなんだから。



41
42
43
# File 'lib/norm_dist.rb', line 41

def normal_cdf(x, mu, sigma)
  Distribution::Normal.cdf((x - mu) / sigma)
end

.normal_cdf_calc(x, mu, sigma, calc_range_multiple: 10.0, steps: 25000) ⇒ Object

自力で累積正規分布関数を構築 calc_range_multiple: 積分開始点の平均値からの距離(σのcalc_range_multiple倍として定義) steps: 積分ステップ数



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/norm_dist.rb', line 18

def normal_cdf_calc(x, mu, sigma, calc_range_multiple: 10.0, steps: 25000)
  ### 積算する範囲設定 この調整がむずい
  len = sigma*calc_range_multiple < (x-mu).abs * 2 ? (x-mu).abs * 2 : sigma * calc_range_multiple
  step_len = (x-(mu-len)) / steps
  calc_range = ((mu-len)..x).step(step_len)
  ###
  
  cdf = calc_range.inject(0.0) do |result, cx|
    pdf1 = normal_pdf(cx-step_len, mu, sigma)
    pdf2 = normal_pdf(cx, mu, sigma)
    plus = (pdf1 + pdf2) * step_len / 2.0
    result += plus
  end
  return cdf
end

.normal_pdf(x, mu, sigma) ⇒ Object

標準化を使用するパターン



35
36
37
# File 'lib/norm_dist.rb', line 35

def normal_pdf(x, mu, sigma)
  Distribution::Normal.pdf((x - mu) / sigma) / sigma
end

.normal_pdf_calc(x, mu, sigma) ⇒ Object

自力で正規分布関数を構築



10
11
12
13
# File 'lib/norm_dist.rb', line 10

def normal_pdf_calc(x, mu, sigma)
  expo = -(((x - mu) ** 2) / (2 * (sigma ** 2)))
  return 1.0 / Math::sqrt(2.0 * Math::PI * (sigma ** 2.0)) * Math::exp(expo)
end

.t_inv(f, p, max: 10, step: 1e-4) ⇒ Object

両側



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/norm_dist.rb', line 101

def t_inv(f, p, max:10, step: 1e-4)
  x = max
  
  # 最初のwhileを通すよう初期値設定
  t = 1.1
  
  while t > 1.0 - (1.0 - p) / 2.0
    t = Distribution::T.cdf(x, f)
    x -= step
  end
  return [x, -x]
end

.t_inv_l(f, p, min: -10,, step: 1e-4) ⇒ Object

左側



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/norm_dist.rb', line 87

def t_inv_l(f, p, min: -10, step: 1e-4)
  x = min
  
  # 最初のwhileを通すよう初期値設定
  t = -0.1
  
  while t < 1 - p
    t = Distribution::T.cdf(x, f)
    x += step
  end
  return x
end

.t_inv_r(f, p, max: 10, step: 1e-4) ⇒ Object

右側



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/norm_dist.rb', line 73

def t_inv_r(f, p, max: 10, step: 1e-4)
  x = max
  
  # 最初のwhileを通すよう初期値設定
  t = 1.1
  
  while t > p
    t = Distribution::T.cdf(x, f)
    x -= step
  end
  return x
end