假設我有一個數組:adata=array([0.5, 1.,2.,3.,6.,10.])
,並且我想計算該陣列的威布爾分佈的對數似然性,給定參數[5.,1.5]
和[5.1,1.6]
。我從未想過我需要爲此任務編寫自己的威布爾概率密度函數,因爲它已在scipy.stat.distributions
中提供。所以,這應該做到這一點:「scipy.stat.distributions」的內建概率密度函數是否比用戶提供的慢?
from scipy import stats
from numpy import *
adata=array([0.5, 1.,2.,3.,6.,10.])
def wb2LL(p, x): #log-likelihood of 2 parameter Weibull distribution
return sum(log(stats.weibull_min.pdf(x, p[1], 0., p[0])), axis=1)
和:
>>> wb2LL(array([[5.,1.5],[5.1,1.6]]).T[...,newaxis], adata)
array([-14.43743911, -14.68835298])
或者我另起爐竈譜寫新的韋伯PDF功能,如:
wbp=lambda p, x: p[1]/p[0]*((x/p[0])**(p[1]-1))*exp(-((x/p[0])**p[1]))
def wb2LL1(p, x): #log-likelihood of 2 paramter Weibull
return sum(log(wbp(p,x)), axis=1)
和:
>>> wb2LL1(array([[5.,1.5],[5.1,1.6]]).T[...,newaxis], adata)
array([-14.43743911, -14.68835298])
不可否認,我總是認爲這是理所當然的如果已經在scipy
中,它應該非常優化,重新發明車輪很少會使其更快。但是有驚喜:如果我timeit
,0100000呼叫wb2LL1(array([[5.,1.5],[5.1,1.6]])[...,newaxis], adata)
需要2.156s,而100000呼叫wb2LL(array([[5.,1.5],[5.1,1.6]])[...,newaxis], adata)
需要5.219s,內置stats.weibull_min.pdf()
慢兩倍以上。
檢查源代碼python_path/sitepackage/scipy/stat/distributions.py
沒有提供一個簡單的答案,至少對我而言。如果有的話,我希望stats.weibull_min.pdf()
幾乎和wbp()
一樣快。
相關的源代碼:線2999-3033:
class frechet_r_gen(rv_continuous):
"""A Frechet right (or Weibull minimum) continuous random variable.
%(before_notes)s
See Also
--------
weibull_min : The same distribution as `frechet_r`.
frechet_l, weibull_max
Notes
-----
The probability density function for `frechet_r` is::
frechet_r.pdf(x, c) = c * x**(c-1) * exp(-x**c)
for ``x > 0``, ``c > 0``.
%(example)s
"""
def _pdf(self, x, c):
return c*pow(x,c-1)*exp(-pow(x,c))
def _logpdf(self, x, c):
return log(c) + (c-1)*log(x) - pow(x,c)
def _cdf(self, x, c):
return -expm1(-pow(x,c))
def _ppf(self, q, c):
return pow(-log1p(-q),1.0/c)
def _munp(self, n, c):
return special.gamma(1.0+n*1.0/c)
def _entropy(self, c):
return -_EULER/c - log(c) + _EULER + 1
frechet_r = frechet_r_gen(a=0.0, name='frechet_r', shapes='c')
weibull_min = frechet_r_gen(a=0.0, name='weibull_min', shapes='c')
所以,問題是:stats.weibull_min.pdf()
真的慢?如果是這樣,怎麼回事?
我可能會對手寫的數據有一些數值穩定性問題。補償可能會在內置功能中消耗一些時間。 – user2357112
我感覺一樣,有點對scipy/python失去信心。庫函數沒有我期望的那麼先進。 – colinfang
@colinfang,'scipy','%timeit ss.weibull_min.pdf(0.1 * np.arange(1,11),5.,scale = 1)'報告'1000循環,最好每個循環3:595μs '。在'R'中,基準(pweibull((1:10)* 0.1,5,1),複製= 10^6)報告總共22.83秒。作爲一種編程語言,'python'可以說比'R'好得多。但很多時候,我也希望'scipy'庫函數可以更快。 –