将Python Scipy truncnorm模型拟合到观测值,然后采样

将Python Scipy truncnorm模型拟合到观测值,然后采样,python,python-2.7,statistics,scipy,random-sample,Python,Python 2.7,Statistics,Scipy,Random Sample,我正在努力使用Scipy truncnorm拟合方法,我希望得到帮助,使拟合参数系数与观测数据一致 例如,我从N(0,1)分布的右尾创建了一个小样本(其中观测值大于2个stdev),并加入了一些异常值 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.stats import truncnorm values = np.array([2.01, 2.06, 2.71, 2.3

我正在努力使用Scipy truncnorm拟合方法,我希望得到帮助,使拟合参数系数与观测数据一致

例如,我从N(0,1)分布的右尾创建了一个小样本(其中观测值大于2个stdev),并加入了一些异常值

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import truncnorm

values = np.array([2.01,  2.06,  2.71,  2.31,  2.58,  2.17,  3.03,  2.24,  2.12,
                   2.72,  2.46,  2.66,  2.49,  3.41,  2.46,  2.12,  2.12,  2.65,
                   2.32,  2.49,  5.15,  2.62,  2.48,  2.27,  2.05])
pd.Series(values).describe()
然后生成以下汇总统计信息:

count    25.000
mean      2.548
std       0.633
min       2.01
25%       2.17
50%       2.46
75%       2.65
max       5.15
为了说明scipy拟合方法存在的问题,并更好地理解truncnorm实现,我构建了以下直观模型,从检查上述汇总统计数据和采样直方图到观察值(见下图)。我正在努力解决的是,当我尝试使用估计参数进行采样时,为什么拟合方法会给出如此糟糕的结果?如果我没有正确使用拟合结果或犯了其他错误,我将感谢您对转换的帮助

构建这些示例的代码:

size = 10000
bins = 30
intuitive_models = {"model1":(2, 5),
                    "model2":(1, 4, 1),
                    "model3":(0.8, 4, 1, 1.25),
                    "fitted":truncnorm.fit(values)}

# store the tuncnorm random sample into a dict
model_results = dict()
for model, params in intuitive_models.items():
    model_results[model] = truncnorm(*params).rvs(size)

# plot the random sample vs the oserved values
for model, params in intuitive_models.iteritems():
    plt.figure()
    plt.hist(model_results[model], bins=bins, normed=True)
    plt.title(model + ': ' + repr(params))
    plt.hist(values, normed=True, alpha=0.5)

# tabular comparison    
print pd.DataFrame(model_results).describe()
产生了以下表格数据:

             fitted        model1        model2        model3 
count  10000.000000  10000.000000  10000.000000  10000.000000 
mean       1.024707      2.372819      2.524923      2.698601 
std        0.014362      0.333144      0.443857      0.584215 
min        1.000019      2.000040      2.000007      2.000019 
25%        1.012248      2.121838      2.181642      2.245088 
50%        1.024518      2.280975      2.407814      2.557983 
75%        1.036996      2.534782      2.757778      2.998948 
max        1.049991      4.829619      4.982337      5.905201
谢谢你,伯蒂。 p、 我希望这是一个编码问题,而不是统计问题,这就是为什么我把它贴在这里

--更新日期:2014年8月28日-- 这篇文章的想法是希望通过scipy.stats.truncnorm.fit方法获得一些帮助,在几天内,我构建了自己的笨拙算法。从我与Robert的讨论中,我得到的印象是truncnorm的R或标准实现只需要3个参数。对于稍后来到本文的读者,一旦scipy有了一个改进的拟合引擎,这就是我所估计的(假设我们想要一个渐近右尾)


尝试计算给定每个模型的数据的对数似然(即总和(对数(p(x[i]|模型参数)))。如果拟合过程按预期进行,则应发现拟合模型的对数可能性最大。我怀疑(不确定)你会发现拟合模型的对数似然比其他模型小,这意味着存在一些数值问题——也许拟合函数卡在局部极小值内,或者无法脱离一个几乎平坦的平台。为参数尝试多个随机初始值,并采用具有最大对数似然性的拟合结果。感谢各位的提醒,我不确定我是否正确地完成了这项工作,因为我已经做了很长时间的高级统计,但如果我在对数似然性函数中使用scipy最小化,则是最佳参数(对于此数据集)对于truncnorm=[1.671,4.285,0.0012,1.201]?这似乎是合理的,尽管我不确定这四个参数是什么;我很想知道,因为我预计只有3个参数(即μ、西格玛和截止点),但我不一定要知道,只有你知道。你可以尝试绘制一些区域的对数似然图(例如,绘制二维等高线图,您必须为任何其他参数选择特定值)并验证从对数似然最大化得到的结果是否与您在图中看到的任何峰值一致。我已经做了一些进一步的工作,并实现了一个稍好的算法。我认为[1.728,3.999,-0.38,1.383]更适合于此数据。如果有R方面的经验的人能够证实这一点,您会很感兴趣吗?仅供参考,scipy truncnorm函数有两个截断边界,一个用于左尾,一个用于右尾。这些数字不能是截断法线的参数,对吗?因为右截断必须大于或等于to数据的最大值。(我不知道参数是按什么顺序指定的;也许你应该说。但所有这些都小于最大值,即5.15,因此没有一个是右截断。)顺便说一句,由于你加入了一些异常值,这些数据使得参数拟合问题非常有趣。我发现最大化对数似然的参数实际上有很大的负μ和大的σ。我可以发布一些数值,只要问问。