次のグラフに示す入力データ (黒) のヒストグラムがあります。
Gamma distribution
データ全体ではなく、ヒストグラムの最初の曲線 (最初のモード)に合わせようとしています。前のグラフの緑色のプロットは、を利用する次のコードをGamma distribution
使用してすべてのサンプルに を当てはめた場合に対応します。python
scipy.stats.gamma
img = IO.read(input_file)
data = img.flatten() + abs(np.min(img)) + 1
# calculate dB positive image
img_db = 10 * np.log10(img)
img_db_pos = img_db + abs(np.min(img_db))
data = img_db_pos.flatten() + 1
# data histogram
n, bins, patches = plt.hist(data, 1000, normed=True)
# slice histogram here
# estimation of the parameters of the gamma distribution
fit_alpha, fit_loc, fit_beta = gamma.fit(data, floc=0)
x = np.linspace(0, 100)
y = gamma.pdf(x, fit_alpha, fit_loc, fit_beta)
print '(alpha, beta): (%f, %f)' % (fit_alpha, fit_beta)
# plot estimated model
plt.plot(x, y, linewidth=2, color='g')
plt.show()
このデータの興味深いサブセットのみにフィッティングを制限するにはどうすればよいですか?
Update1 (スライス):
前のヒストグラムの最大値を下回る値のみを保持して入力データをスライスしましたが、結果はあまり説得力がありませんでした。
# slice histogram here
これは、前のコードのコメントの下に次のコードを挿入することで実現されました。
max_data = bins[np.argmax(n)]
data = data[data < max_data]
Update2 (scipy.optimize.minimize):
以下のコードは、scipy.optimize.minimize()
を使用してエネルギー関数を最小化して を見つける方法を示しています(alpha, beta)
。
import matplotlib.pyplot as plt
import numpy as np
from geotiff.io import IO
from scipy.stats import gamma
from scipy.optimize import minimize
def truncated_gamma(x, max_data, alpha, beta):
gammapdf = gamma.pdf(x, alpha, loc=0, scale=beta)
norm = gamma.cdf(max_data, alpha, loc=0, scale=beta)
return np.where(x < max_data, gammapdf / norm, 0)
# read image
img = IO.read(input_file)
# calculate dB positive image
img_db = 10 * np.log10(img)
img_db_pos = img_db + abs(np.min(img_db))
data = img_db_pos.flatten() + 1
# data histogram
n, bins = np.histogram(data, 100, normed=True)
# using minimize on a slice data below max of histogram
max_data = bins[np.argmax(n)]
data = data[data < max_data]
data = np.random.choice(data, 1000)
energy = lambda p: -np.sum(np.log(truncated_gamma(data, max_data, *p)))
initial_guess = [np.mean(data), 2.]
o = minimize(energy, initial_guess, method='SLSQP')
fit_alpha, fit_beta = o.x
# plot data histogram and model
x = np.linspace(0, 100)
y = gamma.pdf(x, fit_alpha, 0, fit_beta)
plt.hist(data, 30, normed=True)
plt.plot(x, y, linewidth=2, color='g')
plt.show()
上記のアルゴリズムは のサブセットに対して収束し、data
の出力o
は次のとおりです。
x: array([ 16.66912781, 6.88105559])
しかし、下のスクリーンショットでわかるように、ガンマ プロットはヒストグラムに適合しません。