2013-05-10 12 views
9

Ho spesso incontrato e realizzato distribuzioni/istogrammi di grado a coda lunga da reti complesse come le figure sottostanti. Fanno la fine pesante di queste code, bene, molto pesante e affollato da molte osservazioni:Ripartizione delle distribuzioni di gradi di una rete da registro

Classic long-tailed degree distribution

Tuttavia, molte pubblicazioni che ho letto hanno una distribuzione molto più pulito di laurea che non hanno questa rugosità alla fine del la distribuzione e le osservazioni sono più uniformemente distanziate.

! Classic long-tailed degree distribution

Come si crea un grafico come questo utilizzando e matplotlib?

+0

Qual è esattamente la domanda qui? Sembra che tu abbia già raggiunto il risultato che stai cercando. Dovrai essere più specifico di "renderlo migliore". – Hooked

+2

Non c'è dubbio, basta condividere come ho risolto un problema e aprendolo al feedback degli altri se ho perso qualcosa nel mio approccio. –

+0

Il modo migliore per farlo, altrimenti si chiuderà, è quello di suddividere questo in una domanda e rispondere da soli. Vedi http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ – Hooked

risposta

11

Utilizzare log binning (see also). Qui è il codice per prendere un oggetto Counter che rappresenta un istogramma di valori di grado e log-bin la distribuzione per produrre una distribuzione più sparsa e più liscia.

import numpy as np 
def drop_zeros(a_list): 
    return [i for i in a_list if i>0] 

def log_binning(counter_dict,bin_count=35): 

    max_x = log10(max(counter_dict.keys())) 
    max_y = log10(max(counter_dict.values())) 
    max_base = max([max_x,max_y]) 

    min_x = log10(min(drop_zeros(counter_dict.keys()))) 

    bins = np.logspace(min_x,max_base,num=bin_count) 

    # Based off of: http://stackoverflow.com/questions/6163334/binning-data-in-python-with-scipy-numpy 
    bin_means_y = (np.histogram(counter_dict.keys(),bins,weights=counter_dict.values())[0]/np.histogram(counter_dict.keys(),bins)[0]) 
    bin_means_x = (np.histogram(counter_dict.keys(),bins,weights=counter_dict.keys())[0]/np.histogram(counter_dict.keys(),bins)[0]) 

    return bin_means_x,bin_means_y 

Generazione di una rete classica scale-free in NetworkX e poi tracciando questo:

import networkx as nx 
ba_g = nx.barabasi_albert_graph(10000,2) 
ba_c = nx.degree_centrality(ba_g) 
# To convert normalized degrees to raw degrees 
#ba_c = {k:int(v*(len(ba_g)-1)) for k,v in ba_c.iteritems()} 
ba_c2 = dict(Counter(ba_c.values())) 

ba_x,ba_y = log_binning(ba_c2,50) 

plt.xscale('log') 
plt.yscale('log') 
plt.scatter(ba_x,ba_y,c='r',marker='s',s=50) 
plt.scatter(ba_c2.keys(),ba_c2.values(),c='b',marker='x') 
plt.xlim((1e-4,1e-1)) 
plt.ylim((.9,1e4)) 
plt.xlabel('Connections (normalized)') 
plt.ylabel('Frequency') 
plt.show() 

produce il seguente diagramma che mostra la sovrapposizione tra la distribuzione "grezzo" in blu e la distribuzione "categorizzata" in rosso.

Comparison between raw and log-binned

Pensieri su come migliorare questo approccio o risposte se ho perso qualcosa di ovvio sono i benvenuti.

+0

ricorda di accettare la tua risposta se ne sei felice! – tacaswell

+0

per noobs, quali sono le etichette x-y qui? – sAguinaga

+0

Le etichette x-y sono: asse x -> il log dei gradi incontrati nella rete; asse y -> il log della frequenza di quei gradi. – FaCoffee

Problemi correlati