簡體   English   中英

安裝定制 Scipy 分布

[英]Fitting a Custom Scipy Distribution

我使用自定義 scipy class 重新定義了對數正態分布。 我已經模擬了這個分布,我試圖恢復我指定的原始參數,但是,fit 方法返回不同的參數。

import numpy as np
import pandas as pd
from scipy.stats import rv_continuous
from scipy.special import erf
from scipy.special import erfinv

class lognorm_v2(rv_continuous):

    def _pdf(self, x, mu, sigma):
        return 1 / (x * sigma * np.sqrt(2 * np.pi)) * np.exp(-0.5 * ((np.log(x) - mu)/sigma)**2)

    def _cdf(self, x, mu, sigma):
        return 0.5 + 0.5 * erf((np.log(x) - mu)/ (np.sqrt(2)*sigma))
    
    def _sf(self, x, mu, sigma):
        u = (x)**b/(1+x**b)
        return 1 - 0.5 + 0.5 * erf((np.log(x) - mu)/ (np.sqrt(2)*sigma))
    
    def _ppf(self,x, mu, sigma):
        return np.exp(sigma * erfinv(2*x - 1) - mu)
    
    def _argcheck(self, mu, sigma):
        s = sigma > 0
        return s

np.random.seed(seed=111)
logn = lognorm_v2(name='lognorm_v2',a=0,b=np.inf)
test = logn.rvs(mu=2,sigma=1,loc=0,scale=1,size=100000)

logn.fit(test)
logn.fit(test,floc=0,fscale=1)

當 loc 和 scale 不固定時,我獲取參數:

(0.9216388162274325, 0.7061876689651909, -0.0003659266464081178, 0.05399544825451739)

當它們被修復時,結果是:

(-2.0007136838780917, 0.7086144279779958, 0, 1)

為什么我無法提取原始模擬中指定的 mu 2 和 sigma 1? 我知道我不會得到確切的值,但對於 100K 模擬,它們應該非常接近。 我的 numpy 是 1.19.2 版本,scipy 是 1.5.2。 謝謝!

我已經用正確的 _ppf 更正了代碼,它似乎為 mu 和 sigma 產生了合適的擬合

代碼,Python 3.9 Windows 10 x64

import numpy as np
from scipy.stats import rv_continuous
from scipy.special import erf
from scipy.special import erfinv

SQRT2 = np.float64(1.4142135623730951)

class lognorm_v2(rv_continuous):

    def _pdf(self, x, μ, σ):
        return 1 / (x * σ * SQRT2 * np.sqrt(np.pi)) * np.exp(-0.5 * ((np.log(x) - μ)/σ)**2)

    def _cdf(self, x, μ, σ):
        return 0.5 + 0.5 * erf((np.log(x) - μ)/ (SQRT2*σ))

    def _ppf(self, x, μ, σ):
        return np.exp(μ + σ * SQRT2 * erfinv(2.0*x - 1.0))

    def _argcheck(self, μ, σ):
        s = σ > 0.0
        return s

np.random.seed(seed=111)
logn = lognorm_v2(name='lognorm_v2', a=0.0, b=np.inf)
test = logn.rvs(μ=2.0,σ=1.0,loc=0.0,scale=1.0, size=100000)

logn.fit(test,floc=0,fscale=1)

打印出來

(1.9990788106319746, 1.0021523463000124, 0, 1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM