2012-01-02 3 views
4

いくつかのデータを対数正規分布に近似しようとしており、これから最適化されたパラメータを使ってランダムな対数正規分布を生成しています。 は、いくつかの検索後、私はいくつかの解決策を見つけましたが、どれも説得力:フィット関数を使用して観測データの形状を使ってランダムな対数正規分布を生成する

ソリューション1:元のデータからmuとsigmaを使用して

import numpy as np 
from scipy.stats  import lognorm 

mydata = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354] 

shape, loc, scale = lognorm.fit(mydata) 
rnd_log = lognorm.rvs (shape, loc=loc, scale=scale, size=100) 

や解決方法2:

import numpy as np 
from scipy.stats  import lognorm 

mydata = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354] 

mu = np.mean([np.log(i) for i in mydata]) 
sigma = np.std([np.log(i) for i in mydata]) 

distr = lognorm(mu, sigma) 
rnd_log = distr.rvs (size=100) 

これらのソリューションのどれもうまく適合しません。

import pylab 
pylab.plot(sorted(mydata, reverse=True), 'ro') 
pylab.plot(sorted(rnd_log, reverse=True), 'bx') 

私はうまくディストリビューションを使用する方法を理解している場合、私はわからない、または私は何か他のものをしないのです場合...

私もここで解決策を見つける:Does anyone have example code of using scipy.stats.distributions? が、私は形状を取得することはできませんよ私のデータから...フィット関数の使用に何か不足していますか?

おかげ

EDIT:

が、これはより良い私の問題を理解するために例です:

print 'solution 1:' 
means = [] 
stdes = [] 
distr = lognorm(mu, sigma) 
for _ in xrange(1000): 
    rnd_log = distr.rvs (size=100) 
    means.append (np.mean([np.log(i) for i in rnd_log])) 
    stdes.append (np.std ([np.log(i) for i in rnd_log])) 
print 'observed mean:',mu , 'mean simulated mean:', np.mean (means) 
print 'observed std :',sigma, 'mean simulated std :', np.mean (stdes) 

print '\nsolution 2:' 
means = [] 
stdes = [] 
shape, loc, scale = lognorm.fit(mydata) 
for _ in xrange(1000): 
    rnd_log = lognorm.rvs (shape, loc=loc, scale=scale, size=100) 
    means.append (np.mean([np.log(i) for i in rnd_log])) 
    stdes.append (np.std ([np.log(i) for i in rnd_log])) 
print 'observed mean:',mu , 'mean simulated mean:', np.mean (means) 
print 'observed std :',sigma, 'mean simulated std :', np.mean (stdes) 

結果は次のとおりです。

solution 1: 
observed mean: 1.82562655734 mean simulated mean: 1.18929982267 
observed std : 1.39003773799 mean simulated std : 0.88985924363 

solution 2: 
observed mean: 1.82562655734 mean simulated mean: 4.50608084668 
observed std : 1.39003773799 mean simulated std : 5.44206119499 
私はRで同じことを行う場合

しばらくは、:

mydata <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354) 
meanlog <- mean(log(mydata)) 
sdlog <- sd(log(mydata)) 
means <- c() 
stdes <- c() 
for (i in 1:1000){ 
    rnd.log <- rlnorm(length(mydata), meanlog, sdlog) 
    means <- c(means, mean(log(rnd.log))) 
    stdes <- c(stdes, sd(log(rnd.log))) 
} 

print (paste('observed mean:',meanlog,'mean simulated mean:',mean(means),sep=' ')) 
print (paste('observed std :',sdlog ,'mean simulated std :',mean(stdes),sep=' ')) 

は私が取得:

[1] "observed mean: 1.82562655733507 mean simulated mean: 1.82307191072317" 
[1] "observed std : 1.39704049131865 mean simulated std : 1.39736545866904" 
はるかに近い

ので、私はscipyのダウンロードを使用しているとき、私は何か間違ったことをやっていると思います。 ..

+1

何このmydata配列ですか?フィッティングについては、xの値とyの値を見たいと思います...この配列をどのように解釈する必要がありますか? – Tanriol

+0

[対数正規分布のパラメータ推定に関する多くの論文](http://scholar.google.com/scholar?q=lognormal+parameter+estimation&hl=ja&as_sdt=0&as_vis=1&oi=scholart)のいずれかを見ましたか? –

+0

大丈夫、申し訳ありませんが、私の質問は十分にはっきりしていないと思います。私はそれを編集する。 – fransua

答えて

4

scipyの対数正規分布は、通常の方法とは少し異なります。 scipy.stats.lognormドキュメント、特に「注」セクションを参照してください。

ここでは、(ときフィッティング我々は0に位置を保持することに注意してください)期待している結果を取得する方法は次のとおりです。今、あなたがサンプルを生成し、あなたの期待を確認することができ

In [315]: from scipy import stats 

In [316]: x = np.array([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354]) 

In [317]: mu, sigma = stats.norm.fit(np.log(x)) 

In [318]: mu, sigma 
Out[318]: (1.8256265573350701, 1.3900377379913127) 

In [319]: shape, loc, scale = stats.lognorm.fit(x, floc=0) 

In [320]: np.log(scale), shape 
Out[320]: (1.8256267737298788, 1.3900309739954713) 

を:

In [321]: dist = stats.lognorm(shape, loc, scale) 

In [322]: means, sds = [], [] 

In [323]: for i in xrange(1000): 
    .....:  sample = dist.rvs(size=100) 
    .....:  logsample = np.log(sample) 
    .....:  means.append(logsample.mean()) 
    .....:  sds.append(logsample.std()) 
    .....: 

In [324]: np.mean(means), np.mean(sds) 
Out[324]: (1.8231068508345041, 1.3816361818739145) 
+0

素晴らしい!どうもありがとう!はい、私は医者のメモを見ましたが、それはまだ私にとって明らかではありませんでした。あなたが影響を与えることができるかどうかはわかりませんが、私のような初心者にとってはこのような例が役に立つでしょう:)。最後に、random.lognormvariate(mu、sigma)を使用した他の解決策が見つかりましたが、これは確実に優れています! – fransua

関連する問題