Domanda

Questo è un problema che ho tormentando il mio cervello per un lungo periodo di tempo, in modo che qualsiasi aiuto sarebbe grande. Ho un file che contiene diverse righe nel seguente formato (parola, momenti che la parola si è verificato in, e la frequenza di documenti che contengono la parola data colloca nel caso nel tempo). Di seguito è riportato un esempio di ciò che gli sguardi InputFile simili.

#inputfile
<word, time, frequency>
apple, 1, 3
banana, 1, 2
apple, 2, 1
banana, 2, 4
orange, 3, 1

Ho classe Python inferiore a quello che ho usato per creare dizionari 2-D per memorizzare il file di cui sopra utilizzando come chiave, e la frequenza come valore:

class Ddict(dict):
    '''
    2D dictionary class
    '''
    def __init__(self, default=None):
            self.default = default

    def __getitem__(self, key):
            if not self.has_key(key):
                self[key] = self.default()
            return dict.__getitem__(self, key)


wordtime=Ddict(dict) # Store each inputfile entry with a <word,time> key
timeword=Ddict(dict) # Store each inputfile entry with a <time,word> key

# Loop over every line of the inputfile
for line in open('inputfile'):
    word,time,count=line.split(',')

    # If <word,time> already a key, increment count
    try:
        wordtime[word][time]+=count
    # Otherwise, create the key
    except KeyError:
        wordtime[word][time]=count

    # If <time,word> already a key, increment count     
    try:
        timeword[time][word]+=count
    # Otherwise, create the key
    except KeyError:
        timeword[time][word]=count

La domanda che ho riguarda il calcolo certe cose, mentre l'iterazione di voci di questo dizionario 2D. Per ogni parola 'w' in ogni momento 't', calcola:

  1. Il numero di documenti parola 'w' all'interno di di tempo 't'. (A)
  2. Il numero di documenti senza parola 'w' all'interno di di tempo 't'. (B)
  3. Il numero di documenti parola 'w' fuori di tempo 't'. (C)
  4. Il numero di documenti senza parola 'w' fuori di tempo 't'. (D)

Ognuno degli elementi sopra rappresenta una delle celle di una tabella di contingenza chi-quadrato per ogni parola e tempo. Può tutto questo essere calcolata all'interno di un singolo ciclo o hanno bisogno di essere uno fatto in un momento?

Idealmente, vorrei l'uscita di essere ciò che è al di sotto, dove a, b, c, d sono tutti gli elementi calcolati sopra:

print "%s, %s, %s, %s" %(a,b,c,d)

Nel caso del file di input sopra, il risultato del tentativo di trovare la tabella di contingenza per la parola 'mela' in fase di '1' sarebbe (3,2,1,6). Spiegherò come viene calcolato ogni cella:

  • documenti '3' contengono 'apple' all'interno tempo di '1'.
  • Non ci sono documenti '2' entro il tempo '1' che non contengono 'mela'.
  • Non v'è '1' documento contenente 'Apple' fuori dal tempo '1'.
  • Ci sono 6 i documenti di fuori del tempo '1' che non contengono la parola 'Mela' (1 + 4 + 1).
È stato utile?

Soluzione

I tuoi 4 numeri per Apple / 1 aggiungere fino a 12, più del numero totale di osservazioni (11)! Ci sono solo 5 i documenti fuori del tempo '1' che non contengono la parola 'mela'.

È necessario suddividere le osservazioni in 4 sottoinsiemi disgiunti:
un: mela e 1 => 3
B: Non-mela e 1 => 2
C: Apple e non-1 => 1
D: Non-mela e non-1 => 5

Ecco un codice che mostra un modo di farlo:

from collections import defaultdict

class Crosstab(object):

    def __init__(self):
        self.count = defaultdict(lambda: defaultdict(int))
        self.row_tot = defaultdict(int)
        self.col_tot = defaultdict(int)
        self.grand_tot = 0

    def add(self, r, c, n):
        self.count[r][c] += n
        self.row_tot[r] += n
        self.col_tot[c] += n
        self.grand_tot += n

def load_data(line_iterator, conv_funcs):
    ct = Crosstab()
    for line in line_iterator:
        r, c, n = [func(s) for func, s in zip(conv_funcs, line.split(','))]
        ct.add(r, c, n)
    return ct

def display_all_2x2_tables(crosstab):
    for rx in crosstab.row_tot:
        for cx in crosstab.col_tot:
            a = crosstab.count[rx][cx]
            b = crosstab.col_tot[cx] - a
            c = crosstab.row_tot[rx] - a
            d = crosstab.grand_tot - a - b - c
            assert all(x >= 0 for x in (a, b, c, d))
            print ",".join(str(x) for x in (rx, cx, a, b, c, d))

if __name__ == "__main__":

    # inputfile
    # <word, time, frequency>
    lines = """\
    apple, 1, 3
    banana, 1, 2
    apple, 2, 1
    banana, 2, 4
    orange, 3, 1""".splitlines()

    ct = load_data(lines, (str.strip, int, int))
    display_all_2x2_tables(ct)

e qui è l'output:

orange,1,0,5,1,5
orange,2,0,5,1,5
orange,3,1,0,0,10
apple,1,3,2,1,5
apple,2,1,4,3,3
apple,3,0,1,4,6
banana,1,2,3,4,2
banana,2,4,1,2,4
banana,3,0,1,6,4
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top