7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

最尤法による2母数ワイブル分布の母数推定 [理論・実装(python)]

Last updated at Posted at 2024-10-20

はじめに

pythonの勉強中なので、少しプログラムを書いてみました。
途中、少し、計算過程を記載していますが、、温かい目でお願いします。

目的・テーマ

以下に示す2母数ワイブル分布の母数推定について勉強してみました。
ここで、α、βをそれぞれ尺度母数、形状母数です。
分布の形状を決めるパラメータですね。

f(x;\alpha,\beta) = \frac{\beta}{\alpha} \left( \frac{x}{\alpha} \right)^{\beta - 1} \exp \left[ - \left( \frac{x}{\alpha} \right)^\beta \right]

今回は最尤法を用いて2母数ワイブル分布の母数推定にチャレンジしようと思います。

理論編

2母数ワイブル分布が上記の式で表される時、尤度関数は以下のようになります。

\begin{aligned}
L(\alpha,\beta) &= \prod_{i=1}^{n}f(x_i;\alpha,\beta) \\

&= \prod_{i=1}^{n}\frac{\beta}{\alpha} \left( \frac{x_i}{\alpha} \right)^{\beta - 1} \exp \left[ - \left( \frac{x_i}{\alpha} \right)^\beta \right]  -①

\end{aligned}

対数尤度関数は以下のようになります。

\log L(\alpha,\beta) = \log \prod_{i=1}^{n}\frac{\beta}{\alpha} \left( \frac{x_i}{\alpha} \right)^{\beta - 1} \exp \left[ - \left( \frac{x_i}{\alpha} \right)^\beta \right]  -②

まずは式②の右辺をわかりやすくしましょう。

\begin{aligned}
\log L(\alpha,\beta) &= \log \prod_{i=1}^{n}\frac{\beta}{\alpha} \left( \frac{x_i}{\alpha} \right)^{\beta - 1} \exp \left[ - \left( \frac{x_i}{\alpha} \right)^\beta \right] \\

&= \log (\frac{\beta}{\alpha})^n \prod_{i=1}^{n} \left( \frac{x_i}{\alpha} \right)^{\beta - 1} \exp \left[ - \left( \frac{x_i}{\alpha} \right)^\beta \right] \\

&= \log (\frac{\beta}{\alpha})^n \prod_{i=1}^{n} \left( \frac{x_i}{\alpha} \right)^{\beta - 1} \prod_{i=1}^{n}\exp \left[ - \left( \frac{x_i}{\alpha} \right)^\beta \right] \\

&= n\log (\frac{\beta}{\alpha}) + (\beta - 1)\sum_{i=1}^{n} \log(\frac{x_i}{\alpha}) -  \sum_{i=1}^{n}(\frac{x_i}{\alpha})^\beta 
 -②'

\end{aligned} \\

以下の式を用いて、α、βの値を求めます。

\begin{aligned}
\frac{\partial \log L(\alpha,\beta)}{\partial \alpha} &= 0 -③ \\
\frac{\partial \log L(\alpha,\beta)}{\partial \beta} &= 0  -④
\end{aligned}

式②'を踏まえて、式③、④の左辺を計算してみましょう。
(式②'をαで偏微分する)

\begin{aligned}

\frac{\partial \log L(\alpha,\beta)}{\partial \alpha} &= -\frac{n}{\alpha} +(1-\beta)\sum_{i=1}^{n}(\frac{1}{\alpha})+\sum_{i=1}^{n}(\frac{\beta x_i^\beta}{\alpha^{\beta+1}}) \\

&= -\frac{n}{\alpha} + \frac{n}{\alpha} - \frac{n\beta}{\alpha} + \frac{\beta}{\alpha}\sum_{i=1}^{n}(\frac{x_i}{\alpha})^\beta \\

&= - \frac{n\beta}{\alpha} + \frac{\beta}{\alpha}\sum_{i=1}^{n}(\frac{x_i}{\alpha})^\beta -⑤\\

\end{aligned} \\

(式②'をβで偏微分する)

\begin{aligned}
\frac{\partial \log L(\alpha,\beta)}{\partial \beta} &= \frac{n}{\beta} + \sum_{i=1}^{n}\log (\frac{x_i}{\alpha})-  \sum_{i=1}^{n}(\frac{x_i}{\alpha})^\beta \log(\frac{x_i}{\alpha}) \\

&= \frac{n}{\beta} + \sum_{i=1}^{n}\log(x_i) - \sum_{i=1}^{n}\log(\alpha)-\frac{1}{\alpha^\beta}\sum_{i=1}^{n}(x_i)^\beta\log x_i+\frac{\log\alpha}{\alpha^\beta} \sum_{i=1}^{n}x_i^\beta \\

&= \frac{n}{\beta} + \sum_{i=1}^{n}\log(x_i) - n\log(\alpha)-\frac{1}{\alpha^\beta}\sum_{i=1}^{n}(x_i)^\beta\log x_i+\frac{\log\alpha}{\alpha^\beta} \sum_{i=1}^{n}x_i^\beta -⑥\\
         
\end{aligned} \\

式③、⑤より、

\begin{aligned}
-\frac{n\beta}{\alpha} + \frac{\beta}{\alpha}\sum_{i=1}^{n}(\frac{x_i}{\alpha})^\beta &= 0 \\

\frac{\beta}{\alpha^{\beta + 1}}\sum_{i=1}^{n}(x_i^\beta) &= \frac{n\beta}{\alpha} \\

\alpha \sum_{i=1}^{n}(x_i^\beta) &= n \alpha^{\beta + 1} \\

\sum_{i=1}^{n}(x_i^\beta) &= n \alpha^{\beta} \\

\alpha^{\beta} &= \frac{\sum_{i=1}^{n}(x_i^\beta)}{n} -⑦\\

\alpha &= (\frac{\sum_{i=1}^{n}(x_i^\beta)}{n})^{\frac{1}{\beta}} \\

\end{aligned} \\

式④、⑥より、

\begin{aligned}
\frac{n}{\beta} + \sum_{i=1}^{n}\log(x_i) - n\log(\alpha)-\frac{1}{\alpha^\beta}\sum_{i=1}^{n}(x_i)^\beta\log x_i+\frac{\log\alpha}{\alpha^\beta} \sum_{i=1}^{n}x_i^\beta &= 0 \\


-\frac{1}{\beta} - \frac{1}{n}\sum_{i=1}^{n}\log(x_i) + \log(\alpha)
+\frac{1}{n\alpha^\beta}\sum_{i=1}^{n}(x_i)^\beta\log x_i-\frac{\log\alpha}{n\alpha^\beta} \sum_{i=1}^{n}x_i^\beta &= 0 \\

\frac{1}{n\alpha^\beta}\sum_{i=1}^{n}(x_i)^\beta\log x_i-\frac{\log\alpha}{n\alpha^\beta} \sum_{i=1}^{n}x_i^\beta+ \log(\alpha)  - \frac{1}{n}\sum_{i=1}^{n}\log(x_i)-\frac{1}{\beta} &= 0 -⑧\\

\end{aligned} \\

式⑦、⑧より、

\begin{aligned}

\frac{1}{n}\frac{1}{\alpha^\beta}\sum_{i=1}^{n}(x_i)^\beta\log x_i-\frac{\log\alpha}{n}\frac{1}{\alpha^\beta} \sum_{i=1}^{n}x_i^\beta+ \log(\alpha)  - \frac{1}{n}\sum_{i=1}^{n}\log(x_i)-\frac{1}{\beta} &= 0 \\

\frac{1}{n}\frac{n}{\sum_{i=1}^{n}(x_i^\beta)}\sum_{i=1}^{n}(x_i)^\beta\log x_i-\frac{\log\alpha}{n}\frac{n}{\sum_{i=1}^{n}(x_i^\beta)} \sum_{i=1}^{n}x_i^\beta+ \log(\alpha)  - \frac{1}{n}\sum_{i=1}^{n}\log(x_i)-\frac{1}{\beta} &= 0 \\

\frac{\sum_{i=1}^{n}(x_i)^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)}- \frac{1}{n}\sum_{i=1}^{n}\log(x_i)-\frac{1}{\beta} &= 0 \\

\beta &= 1 / (\frac{\sum_{i=1}^{n}(x_i)^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)}- \frac{1}{n}\sum_{i=1}^{n}\log(x_i) ) -⑨\\

\end{aligned} \\

まとめると

\begin{aligned}

\alpha &= (\frac{\sum_{i=1}^{n}(x_i^\beta)}{n})^{\frac{1}{\beta}} \\


\beta &= 1 / (\frac{\sum_{i=1}^{n}(x_i)^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)}- \frac{1}{n}\sum_{i=1}^{n}\log(x_i) ) \\

\end{aligned} \\

形状母数βが既知の場合、尺度母数αは計算できそうですね。
他方、形状母数βは両辺にβがいるので、このままだと少し難しいですね。

そこで、今回は以下のような方針でα、βの値を推定しようと思います。

  • 1.ニュートン法を用いてβの値を推定する
  • 2.推定したβを用いて、αの値を計算する

これから、ニュートン法を用いてβの値を求めるための準備をしましょう。

\begin{aligned}

\frac{\sum_{i=1}^{n}(x_i)^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)}- \frac{1}{n}\sum_{i=1}^{n}\log(x_i)-\frac{1}{\beta} &= 0 \\

\frac{1}{\beta} + \frac{1}{n}\sum_{i=1}^{n}\log(x_i) - \frac{\sum_{i=1}^{n}(x_i)^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)} &= 0 \\
\end{aligned} \\

f(β)を以下のように定義します。

\begin{aligned}
f(\beta) = \frac{1}{\beta} + \frac{1}{n}\sum_{i=1}^{n}\log(x_i) - \frac{\sum_{i=1}^{n}(x_i)^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)} \\

\end{aligned} \\

さらに、f(β)の微文形も用意します。

\begin{aligned}

\frac{\partial \sum_{i=1}^{n}(x_i^\beta)}{\partial \beta} &= \sum_{i=1}^{n}(x_i^\beta\log x_i) \\

\frac{\partial \sum_{i=1}^{n}(x_i)^\beta\log x_i}{\partial \beta} &= \sum_{i=1}^{n}(x_i^\beta\log^2 x_i) \\

\end{aligned} \\
\begin{aligned}

f'(\beta) &= -\frac{1}{\beta^2}-\frac{\sum_{i=1}^{n}x_i^\beta\log^2 x_i\sum_{i=1}^{n}(x_i^\beta)-(\sum_{i=1}^{n}(x_i^\beta\log x_i)^2}{(\sum_{i=1}^{n}(x_i^\beta))^2} \\

 &=-\frac{1}{\beta^2}-\frac{\sum_{i=1}^{n}x_i^\beta\log^2x_i}{\sum_{i=1}^{n}(x_i^\beta)} + (\frac{\sum_{i=1}^{n}x_i^\beta\log x_i}{\sum_{i=1}^{n}(x_i^\beta)})^2

\end{aligned} \\

これでニュートン法によりβを推定する準備ができました。

実装編

この章では、2母数ワイブルの母数推定を行うためのプログラムを作成します。
使用する言語はpythonとしました。

作成するコードのイメージは以下の通りです。

  • 検証用データの作成
  • βの推定用
  • αの推定用

検証用データの作成

この節では、指定したα、βの値を母数とする2母数ワイブル分布に従う乱数Xiを生成します。
先ほどの最尤法によるα、βの定義中のXiを作成するようなイメージです。

なお、検証用データと理論的なワイブル分布の概形を比較し、理論曲線に比べてどの程度一致するか確認します。

この節では以下のような関数を用意しました。

# ワイブル分布に従う乱数データの生成
def generate_weibull_samples(alpha,beta,n_sample):
  xi = alpha * np.random.weibull(beta,n_sample)
  return xi

# 理論的なワイブル分布を計算
def compute_weibull_distribution(alpha,beta,x_stop,step):
  theoretical_x = np.arange(0,x_stop,step)
  theoretical_y = (beta/alpha)*(theoretical_x/alpha)**(beta-1) * np.exp(-(theoretical_x/alpha)**beta)
  return theoretical_x,theoretical_y

# 生成した乱数データの頻度分布とワイブル分布曲線の可視化
def plot_weibull_distribution(xi,theoretical_x,theoretical_y):
  plt.hist(xi,bins=50, density=True, color='g', label="Sample Data")
  plt.plot(theoretical_x, theoretical_y, color='r', label="Theoretical data")
  plt.xlabel('x')
  plt.ylabel('f(x)')
  plt.title('Weibull Distribution vs Sample Data')
  plt.legend()
  plt.show()

作成した関数を実行します。

alpha = 3.0
beta = 2.0
n_sample = 20000 # 生成する乱数のサンプル数
xi = generate_weibull_samples(alpha,beta,n_sample) # ワイブル分布に従う乱数の生成

x_stop = 10
step = 0.1
# 理論的なワイブル分布を計算
theoretical_values = compute_weibull_distribution(alpha,beta,x_stop,step)

# 生成した検証用データと理論曲線の可視化
plot_weibull_distribution(xi,theoretical_values[0],theoretical_values[1])

今回は、このような概形になりました。
検証用データとワイブル分布の理論曲線は概ね合っていますね。
したがって、α、βの推定値がそれぞれ3.0、2.0に近い値となればいいですね。

image.png

母数βの推定

ニュートン法によりβの推定を行います。そのため、先ほど示したf(β)、その微分形f'(β)の定義をプログラム中に記載しています。

# f(β)の定義
#############################################
def fb(beta,xi):
  n = len(xi)
  term1 = 1/beta
  term2 = (1/n) * np.sum(np.log(xi))
  term3 = - np.sum((xi**beta) * np.log(xi)) / np.sum((xi**beta))
  return term1 + term2 + term3
#############################################

# f'(β)の定義
#############################################
def dfb(beta,xi):
  term1 = -1/(beta**2)
  term2 = -np.sum((xi**beta) * (np.log(xi))**2) / np.sum(((xi)**beta))
  term3 = (np.sum((xi**beta) * (np.log(xi))) / np.sum(((xi)**beta) ))**2
  return term1 + term2 + term3
#############################################

# ニュートン法の定義(母数βの推定用)
#############################################
def estimate_beta_newton(beta0,xi):
  beta = beta0
  box = []
  for i in range(100):
    if abs(fb(beta,xi)) < 1.0e-06:
      break
    else:
      # ニュートン法の定義
      beta = beta - fb(beta,xi) / dfb(beta,xi)
      box.append(beta)
  return beta,box
#############################################

estimate_beta_newton関数の戻り値は2つあり、「beta」は推測されたβの値。
boxは収束するまでの途中経過を保存した配列になります。
作成した関数を実行してみます。

alpha = 3.0
beta = 2.0
n_sample = 20000 # 生成する乱数のサンプル数
xi = generate_weibull_samples(alpha,beta,n_sample) # ワイブル分布に従う乱数の生成

# ニュートン法を使ってβの値を推定
beta0 = 4 # 初期値、推定開始値
beta = estimate_beta_newton(beta0,xi)[0]
print(beta) #今回は1.99908526070747

ある程度2.0に近い値が出力されました。
初期値の与え方も重要そうなので、この辺りは今後勉強します。

母数αの推定

前節までのコードによってβの推定ができました。これからαの推定用のプログラムを作成します。

# 母数αの推定用
#############################################
def estimate_alpha(beta,xi):
  n = len(xi)
  alpha = (np.sum(xi ** beta) / n) ** (1/beta)
  return alpha
#############################################
alpha = estimate_alpha(beta,xi)
print("alpha:",alpha) #2.996716351398999

推定値

  • α : 2.996716351398999
  • β : 1.99908526070747

いい感じそう

7
5
0

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
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?