2012-01-30 11 views
7

Come ho fatto qualche analisi dei social network, mi sono imbattuto nel problema di installare una distribuzione di probabilità sul grado di rete.Stima il taglio esponenziale in una distribuzione di legge di potenza

Quindi, ho una distribuzione di probabilità P(X >= x) che, dall'ispezione visiva, segue una legge di potenza con un limite esponenziale piuttosto che una pura legge di potenza (una linea retta).

Quindi, dato che l'equazione per la distribuzione legge di potenza con cut-off esponenziale è:

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

Come potrei stimare i parametri alpha e beta usando Python?

So che il pacchetto scipy.stats.powerlaw esiste e hanno una funzione .fit() ma che non sembra fare il lavoro in quanto restituisce solo la posizione e la scala della trama, che sembra essere utile solo per la normale distribuzione ? Non ci sono abbastanza tutorial su questo pacchetto.

P.S. Sono a conoscenza dell'implementazione di CLauset et al ma non sembrano fornire modi per stimare i parametri delle distribuzioni alternative.

+2

Il La carta Clauset è * la * migliore referenza sull'adattamento pratico delle funzioni di legge di potenza. Se ritieni sinceramente di avere un problema che non viene affrontato, considera l'e-mail agli autori –

+0

Non sono uno statistico, quindi non sono sicuro di capire completamente l'intero documento. Penso che il codice di Ginsberg sia fantastico e molto utile. Voglio solo sapere se ci sono strumenti per aiutare a stimare i parametri di altre distribuzioni di probabilità. – Mike

+0

http://en.wikipedia.org/wiki/Power_law dove è la linea retta di cui parli? –

risposta

3

La funzione scipy.stats.powerlaw.fit può ancora funzionare per i propri scopi. È un po 'di confusione su come funzionano le distribuzioni in scipy.stats (la documentazione per ognuno si riferisce ai parametri opzionali loc e scale, anche se non tutti usano questi parametri, e ognuno li usa in modo diverso). Se si guarda la documentazione:

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

c'è anche un secondo non-optional parametro "a", che è il "parametri di forma". Nel caso di powerlaw, questo contiene un singolo parametro. Non preoccuparti di "loc" e "scala".

Modifica: Scusa, ho dimenticato di volere anche il parametro beta. Il tuo miglior risultato potrebbe essere quello di definire la funzione powerlaw che desideri tu stesso, e quindi utilizzare gli algoritmi di fitting generici di scipy per apprendere i parametri.Ad esempio: http://www.scipy.org/Cookbook/FittingData#head-5eba0779a34c07f5a596bbcf99dbc7886eac18e5

+0

c'è qualche codice giocattolo da testare? –

1

Ecco un mezzo per stimare l'esponente di scala e la velocità esponenziale di legge di potenza con esponenziale cut-off massimizzando probabilità in 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) 
} 

Partenza https://github.com/jeffalstott/powerlaw/ per maggiori informazioni

+0

La risposta è utile ma incompleta, si prega di controllare la mia risposta per una domanda simile utilizzando R a https://stackoverflow.com/a/45800141/4928558 per i passaggi per essere in grado di eseguire il codice condiviso in questa risposta. – atfornes

0

Powerlaw libreria può essere direttamente utilizzato per stimare i parametri come segue:

  1. installare tutti i pitoni dipendenze:

    pip install powerlaw mpmath scipy 
    
  2. Run la misura del pacchetto powerlaw in un ambiente di pitone:

    import powerlaw 
    data = [5, 4, ... ] 
    results = powerlaw.Fit(data) 
    
  3. ottenere i parametri in base ai risultati

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