python - 将数据拟合到分布?


1 10
2 5
3 20
...
...

问题是,有什么自动化的方法来找出这个数据的正确分布和分布参数。

时间:

这是个复杂的问题,没有完美的答案,

对于给定的数据,有两种设置概率分布函数参数的方法:

  1. 最小二乘
  2. 最大似然

在我的经验中,最近几年最大似然是首选的,尽管这可能不是每个领域的情况。

这是如何估算R中参数的具体示例。考虑从高斯分布生成的一组随机点,它均值为0,标准差为1:


x = rnorm( n = 100, mean = 0, sd = 1 )

在R中,有一个标准库使这非常简单:


library(MASS)
params = fitdistr( x,"normal" )
print( params )

这给了我以下输出:


 mean sd 
 -0.17922360 1.01636446 
 ( 0.10163645) ( 0.07186782)

从你的参数中提取日志可能性,如下所示:


print( params$loglik )
[1] -139.5772

当对数可能性接近0时,可能性最大,因此负数越多,数据拟合效果越差。

使用这样的计算工具,可以很容易地估计分布的参数,请考虑以下示例:


x = x[ x >= 0 ]

distributions = c("normal","exponential")

for ( dist in distributions ) {
 print( paste("fitting parameters for", dist ) )
 params = fitdistr( x, dist )
 print( params )
 print( summary( params ) )
 print( params$loglik )
}

指数分布不产生负数,所以我在第一行中删除了它们,输出(这是随机)如下所示:


[1]"fitting parameters for normal"
 mean sd 
 0.72021836 0.54079027 
 (0.07647929) (0.05407903)
 Length Class Mode 
estimate 2 -none- numeric
sd 2 -none- numeric
n 1 -none- numeric
loglik 1 -none- numeric
[1] -40.21074
[1]"fitting parameters for exponential"
 rate 
 1.388468 
 (0.196359)
 Length Class Mode 
estimate 1 -none- numeric
sd 1 -none- numeric
n 1 -none- numeric
loglik 1 -none- numeric
[1] -33.58996

克服参数估计中一些问题的一个技巧是生成大量数据,并将某些数据留给交叉验证。

看看fitdistrplus (http://cran.r-project.org/web/packages/fitdistrplus/index.html )。

  • 未定义
  • 未定义
  • 未定义

这可能比你需要的更一般一些,但可能会给你一些东西。

估计随机数据的概率密度函数的一种方法是使用Edgeworth或者Butterworth扩展。 这些近似使用密度函数属性称为累积量 ( 无偏估计量为 k-statistics ) 和表达密度函数为高斯分布的扰动。

这些都有一些相当严重的弱点,比如产生发散的密度函数,甚至是密度函数,这些函数在某些区域是负的。 但是,有些人发现它们对于高集群数据有用,或者作为远估计的起点,或者用于分段估计密度函数,或者作为启发的一部分。

。G 和A 。 斯图尔特,高级统计理论,vol 。 1查尔斯·格里芬, 1963是我发现的最完整的参考,高达整个页面的主题,其他大多数文献最多有一个句子或上市方面的扩张的时刻,而不是累积量有点用处。 幸运的是找到一份副本,但是我不得不向我的大学管理员发送一个旅行到存档。 但这是很久以前的了,所以也许互联网今天会更有帮助。

你的问题最普遍的形式是已知的non-parametric密度估计的主题,其中给出:

  • 来自具有未知分布的随机进程的数据,
  • 对基础进程的约束

你会产生一个密度函数,它最可能产生数据。 ( 更现实地说,你可以创建一个方法,在任意给定的点计算这个函数的近似值,你可以使用它进行进一步的工作,比如。 比较两组随机数据的密度函数,看看它们是否来自同一个进程。

但就个人而言,我也一直运气不佳在使用non-parametric密度估计任何有用的东西,但是如果你有理智的稳定供应你应该看看它。

我不是一个科学家,但如果你用铅笔做它,显然的方法是制作一个图形,然后把图形比作一个已知的standard-distribution 。

更进一步,"比较"正在寻找standard-distribution和你的曲线是否相似。

三角,切线。是我最后想到的。

我不是专家,只是另一个卑微的网站开发人员=

你基本上想把你的真实世界数据与一组理论分布进行比较。 R 有函数 qqnorm() 基地,这将为正态分布,但我更喜欢在 e1071probplot 函数允许你测试其他发行版。 下面是一个代码 Fragment,它将 plot的真实数据与我们粘贴到列表中的每个理论分布进行对比。 我们使用 plyr 遍历列表,但是还有其他几种方法可以通过列表。


library("plyr") 
library("e1071")

realData <- rnorm(1000) #Real data is normally distributed

distToTest <- list(qnorm ="qnorm", lognormal ="qlnorm", qexp ="qexp")

#function to test real data against list of distributions 上面. Output is a jpeg for each distribution.
testDist <- function(x, data){
 jpeg(paste(x,".jpeg", sep =""))
 probplot(data, qdist = x)
 dev.off()
 }

l_ply(distToTest, function(x) testDist(x, realData))

对于它来说,你似乎想看看泊松分布。

...