2014-09-14 23 views
6

Sto creando un semplice sistema di gestione delle opinioni utilizzando Naive Bayes classifier.Python più veloce alternativa al dizionario?

Per addestrare il mio classificatore, ho un file di testo in cui ogni riga contiene un elenco di token (generato da un tweet) e il sentimento associato (0 per -ve, 4 per positivo).

Ad esempio:

0 @ switchfoot http : //twitpic.com/2y1zl - Awww , that 's a bummer . You shoulda got David Carr of Third Day to do it . ; D 
0 spring break in plain city ... it 's snowing 
0 @ alydesigns i was out most of the day so did n't get much done 
0 some1 hacked my account on aim now i have to make a new one 
0 really do n't feel like getting up today ... but got to study to for tomorrows practical exam ... 

Ora, quello che sto cercando di fare è per ogni token, contare quante volte si verifica in un tweet positivi, e quante volte si verifica in un tweet negativo. Pianifico quindi di utilizzare questi conteggi per calcolare le probabilità. Sto usando il dizionario integrato per la memorizzazione di questi conteggi. Le chiavi sono i token e i valori sono array di numeri interi di dimensioni 2.

Il problema è che questo codice inizia abbastanza velocemente, ma continua a rallentare e quando ha elaborato circa 200 mila tweet, diventa molto lento - in giro 1 tweet al secondo. Dato che il mio set di allenamento ha 1,6 milioni di tweet, questo è troppo lento. Il codice che ho è questa:

def compute_counts(infile): 
    f = open(infile) 
    counts = {} 
    i = 0 
    for line in f: 
     i = i + 1 
     print(i) 
     words = line.split(' ') 
     for word in words[1:]: 
      word = word.replace('\n', '').replace('\r', '') 
      if words[0] == '0': 
       if word in counts.keys(): 
        counts[word][0] += 1 
       else: 
        counts[word] = [1, 0] 
      else: 
       if word in counts.keys(): 
        counts[word][1] += 1 
       else: 
        counts[word] = [0, 1] 
    return counts 

Cosa posso fare per rendere questo processo più veloce? Una struttura dati migliore?

Modifica: non è un duplicato, la domanda non riguarda qualcosa di più veloce di dict nel caso generale, ma in questo caso d'uso specifico.

+0

Invece di chiave di controllo è esiste o no, usano il conteggio [tasto] = counts.get (key, default = None) # è possibile fornire un valore di default nel caso chiave non è presente, verrà creata con il valore predefinito. –

+2

Potresti usare due 'collections.Counter 'invece di un dizionario di liste. –

risposta

10

Non utilizzare if word in counts.keys() Se lo fai, si finisce per guardare in modo sequenziale attraverso i tasti, che è ciò dict si suppone per evitare.

Basta inserire if word in counts.

Oppure utilizzare defaultdict. https://docs.python.org/2/library/collections.html#collections.defaultdict

+1

In Python 2, 'dict.keys()' crea una lista, un'operazione che è probabilmente costosa come la ricerca. Non è il dizionario ad essere lento. –

+0

defaultdict ha funzionato come un incantesimo. In precedenza ho impiegato circa 4 ore per elaborare linee da 200k, ma ora l'intero 1,6 milioni è stato fatto in un minuto. Grazie! – hoodakaushal