Menyesuaikan distribusi log-normal di R vs. SciPy

10

Saya telah memasang model lognormal menggunakan R dengan satu set data. Parameter yang dihasilkan adalah:

meanlog = 4.2991610 
sdlog = 0.5511349

Saya ingin mentransfer model ini ke Scipy, yang belum pernah saya gunakan sebelumnya. Menggunakan Scipy, saya bisa mendapatkan bentuk dan skala 1 dan 3.1626716539637488e + 90 - angka yang sangat berbeda. Saya juga mencoba menggunakan exp dari meanlog dan sdlog tetapi terus mendapatkan grafik yang aneh.

Saya telah membaca setiap dokumen yang saya bisa tentang Scipy dan saya masih bingung tentang apa arti parameter bentuk dan skala dalam contoh ini. Apakah masuk akal untuk kode fungsi sendiri? Itu nampaknya rentan terhadap kesalahan, karena saya baru untuk berhalangan.

SCIPY Lognormal (BLUE) vs. R Lognormal (RED): Scipy Lognormal (BLUE) vs R Lognormal (RED)

Adakah pemikiran tentang arah yang harus diambil? Data cocok dengan model R, omong-omong, jadi jika terlihat seperti sesuatu yang lain di Python, jangan ragu untuk berbagi.

Terima kasih!

Memperbarui:

Saya menjalankan Scipy 0,11

Berikut adalah sebagian dari data. Sampel aktual adalah 38k +, dengan rata-rata 81.53627:

Subset:

x
[60, 170, 137, 138, 81, 140, 78, 46, 1, 168, 138, 148, 145, 35, 82, 126, 66, 147, 88, 106, 80, 54, 83, 83, 13, 102, 54, 134, 34]
numpy.mean (x)
99.071428571428569

Kalau tidak:

Saya sedang mengerjakan fungsi untuk menangkap pdf:

def lognoral(x, mu, sigma):
    a = 1 / (x * sigma * numpy.sqrt(2 * numpy.pi) )
    b = - (numpy.log(x) - mu) ^ 2 / (2 * sigma ^ 2)
    p = a * numpy.exp(b)
    return p

Namun, ini memberi saya angka-angka berikut (saya mencoba beberapa kalau-kalau saya mendapatkan arti sdlog dan meanlog digabungkan):

>>> lognormal(54,4.2991610, 0.5511349)
0.6994656085799437
 >>> lognormal(54,numpy.exp(4.2991610), 0.5511349)
0.9846125119455129
>>> lognormal(54,numpy.exp(4.2991610), numpy.exp(0.5511349))
0.9302407837304372

Adakah pikiran?

Memperbarui:

jalankan kembali dengan saran "UPQuark":

bentuk, loc, skala (1.0, 50.03445923295007, 19.074457156766517)

Namun, bentuk grafiknya sangat mirip, dengan puncaknya sekitar 21.

Lillian Milagros Carrasquillo
sumber
Pertanyaan dan jawaban ini dapat membantu: stackoverflow.com/questions/8747761/…
jbowman
Terima kasih, saya menemukan itu dan belajar "pas" dengan lognormal. Namun, pertanyaan saya adalah mengapa saya mendapat distribusi yang berbeda?
Lillian Milagros Carrasquillo
Apakah Anda menggunakan SciPy 0.9? Juga, bisakah Anda memposting data Anda, atau bagian daripadanya?
jbowman
Diperbarui! Omong-omong, Scipy 0,11. Jadi bug yang saya baca seharusnya tidak relevan;)
Lillian Milagros Carrasquillo

Jawaban:

11

Saya berjuang melalui kode sumber, untuk sampai pada interpretasi rutin lognormal yang ceroboh berikut.

xlocscaleLognormal(σ)

di mana adalah parameter "bentuk". σ

Kesetaraan antara parameter scipy dan parameter R adalah sebagai berikut:

loc - Tidak ada padanan, ini akan dikurangkan dari data Anda sehingga 0 menjadi batas maksimum dari data.

skala - , di mana adalah rata-rata dari log variate. (Saat pas, biasanya Anda akan menggunakan rata-rata sampel dari log data.) μexpμμ

shape - standar deviasi dari log variate.

Saya menyebut masing lognorm.pdf(x, 0.55, 0, numpy.exp(4.29))-masing argumen (x, bentuk, loc, skala), dan menghasilkan nilai berikut:

x pdf

10 0,000106

20 0,002275

30 0,006552

40 0,009979

50 0,114557

60 0,113479

70 0,103327

80 0,008941

90 0,007494

100 0,006155

yang tampaknya cocok dengan kurva R Anda.

Jbowman
sumber
Terima kasih, @JBowman, itulah penjelasan yang saya butuhkan dan hasilnya adalah distribusi saya.
Lillian Milagros Carrasquillo
8

Distribusi lognormal di SciPy cocok dengan kerangka umum untuk semua distribusi di SciPy. Mereka semua memiliki skala dan kata kunci lokasi (yang standarnya 0 dan 1 jika tidak diberikan secara eksplisit). Ini memungkinkan semua distribusi digeser dan diskalakan dari spesifikasi normalnya dengan implikasi yang jelas pada statistik distribusi. Distribusi biasanya memiliki satu atau lebih parameter "bentuk" (meskipun beberapa, seperti distribusi normal, tidak memerlukan parameter tambahan).

Walaupun pendekatan umum ini dengan baik menyatukan semua distribusi, untuk lognormal itu dapat membuat beberapa kebingungan karena cara paket lain mendefinisikan parameter. Namun, sangat mudah untuk mencocokkan distribusi lognormal jika Anda berarti log (rata-rata distribusi yang mendasarinya) dan sdlog (standar deviasi dari distribusi yang mendasarinya).

Pertama, pastikan Anda mengatur parameter lokasi ke 0. Kemudian, atur parameter bentuk ke nilai sdlog. Terakhir, atur parameter skala ke math.exp (meanlog). Dengan demikian, rv = scipy.stats.lognorm (0,5511349, scale = math.exp (4.2991610)) akan membuat objek distribusi yang pdfnya cocok dengan kurva R-yang dihasilkan Anda dengan tepat. As x = numpy.linspace (0,180.1000); plot (x, rv.pdf (x)) akan memverifikasi.

Pada dasarnya, distribusi lognormal SciPy adalah generalisasi dari distribusi lognormal standar yang cocok dengan standar tepat ketika mengatur parameter lokasi ke 0.

Saat mencocokkan data dengan metode .fit, Anda juga dapat menggunakan kata kunci, f0..fn, floc, dan fshape untuk menahan setiap parameter bentuk, lokasi, dan / atau skala yang diperbaiki dan hanya muat di atas variabel lainnya. Untuk distribusi lognormal ini sangat berguna karena biasanya Anda tahu parameter lokasi harus diperbaiki ke 0. Dengan demikian, scipy.stats.lognorm.fit (dataset, floc = 0) akan selalu mengembalikan parameter lokasi sebagai 0 dan hanya memvariasikan parameter lokasi lainnya. parameter bentuk dan skala.

Travis Oliphant
sumber
3

Scipy lognormal fit mengembalikan bentuk, lokasi, dan skala. Saya hanya menjalankan yang berikut ini pada array data harga sampel:

shape, loc, scale = st.lognorm.fit(d_in["price"])

Ini memberi saya perkiraan masuk akal 1.0, 0.09, 0.86, dan ketika Anda memplotnya, Anda harus memperhitungkan ketiga parameter tersebut.

Parameter bentuk adalah simpangan baku dari distribusi normal yang mendasarinya, dan skalanya adalah eksponensial dari rata-rata normal.

Semoga ini membantu.

upquark
sumber
Terima kasih untuk balasannya! Setelah saya memiliki nilai-nilai ini (loc, skala, bentuk), saya mencoba untuk menemukan pdf (x) untuk setiap x yang saya pedulikan (ini adalah nilai dari 0 hingga 180, eksklusif). scipy.stats.lognorm.pdf (i, loc, scale, shape) Namun, memplot ini saya mendapatkan plot di atas.
Lillian Milagros Carrasquillo
OK saya melihat Anda menyebutkan bentuk dan skala saja, itu sebabnya saya sebutkan ada tiga parameter yang dikembalikan secara default dari fit (). Anda juga mengatakan Anda bingung tentang arti parameter bentuk dan skala, dan saya mencoba mengatasinya. Saya tidak pernah memiliki nilai absurd masuk lognormal fit seperti dalam kasus Anda, apa parameter lokasi?
upquark
Baru saja memperbarui pertanyaan untuk menjawabnya. Terima kasih sudah memikirkan ini.
Lillian Milagros Carrasquillo
Panggil scipy.stats.lognorm.pdf (x, bentuk, loc, skala) alih-alih scipy.stats.lognorm.pdf (i, loc, skala, bentuk).
upquark
Terima kasih, upquark, saya telah melakukannya juga dengan hasil yang serupa. Seluruh bentuk grafik terus sangat berbeda dari hasil yang diharapkan memberi dalam R. Sepertinya distribusi yang sama sekali berbeda dari yang ada di R, sebenarnya.
Lillian Milagros Carrasquillo
1

Sepertinya distribusi di Scipy untuk lognormal tidak sama dengan di R, atau secara umum, tidak sama dengan distribusi yang saya kenal. John D Cook telah menyentuh ini: http://www.johndcook.com/blog/2010/02/03/statribution-distributions-in-scipy/ http://www.johndcook.com/distributions_scipy.html

Namun, saya belum menemukan sesuatu yang konklusif tentang cara menggunakan fungsi kepadatan lognormal di Python. Jika ada yang ingin menambahkan ini, silakan saja.

Solusi saya sejauh ini adalah dengan menggunakan pdf lognormal dievaluasi pada 0 hingga 180 (eksklusif), dan digunakan sebagai kamus dalam skrip python.

Lillian Milagros Carrasquillo
sumber