scipyrv\u连续拟合不检查输入数据边界

bq9c1y66  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(360)

我将合成数据拟合到scipy中的各种分布中,但是,我观察到一些意想不到的结果。我的数据包含负数,当我将这些数据与具有非负支持的分布拟合时,在确定位置和比例时,我不会得到错误。我的代码如下:

import scipy.stats as st
import numpy as np
import pandas as pd

np.random.seed(7)
test_data = pd.Series(0.5 + 0.1*np.sin(np.linspace(0, 3*np.pi, 100)) + 0.5*np.random.normal(0,1,size=100))
print(np.min(test_data))

返回:

-0.5900934692403015

确认我产生了负面观察。当我拟合scipy lognorm时,它有一个非包含非负的支持,我得到了一个违反数据界限的错误的预期结果:

st.lognorm.fit(test_data, floc=0, fscale=1)
---------------------------------------------------------------------------
FitDataError                              Traceback (most recent call last)
<ipython-input-13-fbeaae8f3c2e> in <module>
----> 1 st.lognorm.fit(test_data, floc=0, fscale=1)

~\Miniconda3\lib\site-packages\scipy\stats\_continuous_distns.py in fit(self, data, *args,**kwds)
   5087             data = data - floc
   5088         if np.any(data <= 0):
-> 5089             raise FitDataError("lognorm", lower=floc, upper=np.inf)
   5090         lndata = np.log(data)
   5091 

FitDataError: Invalid values in `data`.  Maximum likelihood estimation with 'lognorm' requires that 0.0 < x < inf for each x in `data`.

但是,使用以下分布,我能够拟合数据,尽管所有这些分布都有非负的数据边界(由其scipy文档定义)和固定的位置和规模。

st.burr.fit(test_data, floc=0, fscale=1)

st.expon.fit(test_data)

st.chi2.fit(test_data, floc=0, fscale=1)

st.invgauss.fit(test_data, floc=0, fscale=1)

st.invgamma.fit(test_data, floc=0, fscale=1)

产生:

(4.435119987970436, 0.32475585134451646, 0, 1)
(-0.5900934692403015, 1.1171187649605647)
(1.349414062500001, 0, 1)
(0.6815429687499996, 0, 1)
(2.301074218750003, 0, 1)

此外,没有任何形状参数的分布指数是可以执行的参数,这是令人惊讶的。如果有人能解释这些分布是如何能够适应的数据,尽管事实上,他们的支持边界已被违反我会非常感激。
我正在运行numpy1.19.2和scipy1.5.2
谢谢您!

zphenhs4

zphenhs41#

事实上 fit 没有抛出任何错误并不意味着他们一直是一个很好的适合或他们可以描述你的数据。
我在用 scipy==1.6.1 .
可以检查打印结果

x = np.linspace(test_data.min(), test_data.max(), 100)

毛刺:无错误,bu无法描述<0的数据

burr_pars = sps.burr.fit(test_data, floc=0, fscale=1)
y = sps.burr(*burr_pars).pdf(x)
plt.plot(x, y)
plt.hist(test_data, alpha=.5, density=True);


埃普顿:没有错,但很不合适

expon_pars = sps.expon.fit(test_data)
y = sps.expon(*expon_pars).pdf(x)
plt.plot(x, y)
plt.hist(test_data, alpha=.5, density=True);


chi2:无错误,但拟合非常差,无法描述<0的数据

chi2_pars = sps.chi2.fit(test_data, floc=0, fscale=1)
y = sps.chi2(*chi2_pars).pdf(x)
plt.plot(x, y)
plt.hist(test_data, alpha=.5, density=True);


invgauss:错误

invgauss_pars = sps.invgauss.fit(test_data, floc=0, fscale=1)
FitDataError: Invalid values in `data`.  Maximum likelihood estimation with 'invgauss' requires that 0 < (x - loc)/scale  < inf for each x in `data`.

如果不设置loc和scale,对x>=0最有效,但给定其pdf的公式,没有理由为x<0抛出错误

invgauss_pars = sps.invgauss.fit(test_data)
y = sps.invgauss(*invgauss_pars).pdf(x)
plt.plot(x, y)
plt.hist(test_data, alpha=.5, density=True);


invgamma:警告,不适合,无法描述x<0

invagamm_pars = sps.invgamma.fit(test_data, floc=0, fscale=1)
y = sps.invgauss(*invagamm_pars).pdf(x)
plt.plot(x, y)
plt.hist(test_data, alpha=.5, density=True);
RuntimeWarning: invalid value encountered in double_scalars
  Lhat = muhat - Shat*mu

编辑

从https://github.com/scipy/scipy/blob/v1.6.3/scipy/stats/_continuous_distns.py 你看到了吗 FitDataError 仅由调用 beta , expon (但如果 floc is None 那么 floc = data_min ), gamma , invgauss (但仅限于 np.any(data - floc < 0) ), lognorm , pareto , rayleigh , uniform .
其他分配 FitDataError 未实现。

相关问题