估计幂律分布中的指数截止

时间:2012-01-30 11:26:23

标签: python statistics social-networking

由于我一直在做一些社交网络分析,我偶然发现了在网络度上拟合概率分布的问题。

所以,我有一个概率分布P(X >= x),从视觉检查中,遵循幂指数截止的幂律,而不是纯幂律(直线)。

因此,给定指数截止的幂律分布方程为:

  

f(x)= x ** alpha * exp(beta * x)

如何使用Python估算参数alphabeta

我知道scipy.stats.powerlaw包存在并且它们具有.fit()功能但是它似乎没有完成工作,因为它只返回绘图的位置和比例,这似乎是仅对正态分布有用吗?这个软件包还没有足够的教程。

P.S。我很清楚CLauset et al的实施情况,但他们似乎没有提供估算备用分布参数的方法。

4 个答案:

答案 0 :(得分:3)

函数scipy.stats.powerlaw.fit可能仍然适用于您的目的。 scipy.stats中的发行版如何工作有点令人困惑(每个文档的文档都引用了可选参数loc和scale,即使并非所有参数都使用这些参数,并且每个参数都使用不同的参数)。如果你看一下文档:

http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.powerlaw.html

还有第二个非可选参数“a”,即“形状参数”。在powerlaw的情况下,它包含一个参数。不要担心“loc”和“scale”。

编辑:抱歉,忘了你也想要beta参数。你最好的方法可能是定义你想要的powerlaw函数,然后使用scipy的通用拟合算法来学习参数。例如: http://www.scipy.org/Cookbook/FittingData#head-5eba0779a34c07f5a596bbcf99dbc7886eac18e5

答案 1 :(得分:1)

这是一种通过最大化R中的似然性来估计指数截止的幂律的比例指数和指数率的方法:

# Input: Data vector, lower threshold
# Output: List, giving type ("powerexp"), scaling exponent, exponential rate, lower threshold, log-likelihood


powerexp.fit <- function(data,threshold=1,method="constrOptim",initial_rate=-1) {
  x <- data[data>=threshold]
  negloglike <- function(theta) {
    -powerexp.loglike(x,threshold,exponent=theta[1],rate=theta[2])
  }
  # Fit a pure power-law distribution
  pure_powerlaw <- pareto.fit(data,threshold)
  # Use this as a first guess at the exponent
  initial_exponent <- pure_powerlaw$exponent
  if (initial_rate < 0) { initial_rate <- exp.fit(data,threshold)$rate }
  minute_rate <- 1e-6
  theta_0 <- as.vector(c(initial_exponent,initial_rate))
  theta_1 <- as.vector(c(initial_exponent,minute_rate))
  switch(method,
    constrOptim = {
      # Impose the constraint that rate >= 0
      # and that exponent >= -1
      ui <- rbind(c(1,0),c(0,1))
      ci <- c(-1,0)
      # Can't start with values on the boundary of the feasible set so add
      # tiny amounts just in case
      if (theta_0[1] == -1) {theta_0[1] <- theta_0[1] + minute_rate}
      if (theta_0[2] == 0) {theta_0[2] <- theta_0[2] + minute_rate}
      est <- constrOptim(theta=theta_0,f=negloglike,grad=NULL,ui=ui,ci=ci)
      alpha <- est$par[1]
      lambda <- est$par[2]
      loglike <- -est$value},
    optim = {
      est <- optim(par=theta_0,fn=negloglike)
      alpha <- est$par[1]
      lambda <- est$par[2]
      loglike <- -est$value},
    nlm = {
      est.0 <- nlm(f=negloglike,p=theta_0)
      est.1 <- nlm(f=negloglike,p=theta_1)
      est <- est.0
      if (-est.1$minimum > -est.0$minimum) { est <- est.1;cat("NLM had to switch\n") }
      alpha <- est$estimate[1]
      lambda <- est$estimate[2]
      loglike <- -est$minimum},
    {cat("Unknown method",method,"\n"); alpha<-NA; lambda<-NA; loglike<-NA}
  )
  fit <- list(type="powerexp", exponent=alpha, rate=lambda, xmin=threshold,
              loglike=loglike, samples.over.threshold=length(x))
  return(fit)
}

查看https://github.com/jeffalstott/powerlaw/了解详情

答案 2 :(得分:1)

Powerlaw库可直接用于估算参数,如下所示:

  1. 安装所有pythons依赖项:

    pip install powerlaw mpmath scipy
    
  2. 在python环境中运行powerlaw包:

    import powerlaw
    data = [5, 4, ... ]
    results = powerlaw.Fit(data)
    
  3. 从结果中获取参数

    results.truncated_power_law.parameter1 # power law  parameter (alpha)
    results.truncated_power_law.parameter2 # exponential cut-off parameter (beta)
    

答案 3 :(得分:0)

我也在网络领域工作,我必须做与您非常相似的工作。我找到了一个非常简单快捷的解决方案here,最好的部分是,除了Scipy(我相信您已经拥有)之外,不需要安装任何软件包。

我想要拟合的分布是一个有变化的截止幂定律,例如this paper中描述的那个。使用相同的符号,我适合我

f(x) = (x + x0)**alpha * exp(-beta*x)

因此只需将第三个参数x0添加到您的分布中。请注意,我假设beta是正数,我只是把符号放在外面(我认为这样可以更清楚地表明您的指数在减小)。

实现如下:

import numpy as np.
import scipy.optimize as opt

def distribution(x, alpha, beta, x0):
    return (x + x0)**alpha * np.exp(-beta *x)

# ... I prepare my data here

fit = opt.curve_fit(distribution, x_data, y_data) # you can pass guess for the parameters/errors
alpha, beta, x0 = fit[0]

这是结果:

fit