Question

Ceci est un problème que je suis creusé mon cerveau pendant longtemps, de sorte que toute aide serait super. J'ai un fichier qui contient plusieurs lignes dans le format suivant (mot, le temps que le mot a eu lieu dans, et la fréquence des documents contenant le mot donné dans l'instance donné dans le temps). Ci-dessous un exemple de ce que les INPUTFILE ressemble.

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

Je classe Python ci-dessous que j'utilisés pour créer des dictionnaires 2-D pour stocker le fichier ci-dessus en utilisant comme clé, et la fréquence en tant que valeur:

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 question que je rapporte à calculer certaines choses en itérer sur les entrées dans ce dictionnaire 2D. Pour chaque mot w 'à chaque instant 't', calculer:

  1. Le nombre de documents mot 'w' dans les temps 't'. (A)
  2. Le nombre de documents sans mot 'w' dans les temps 't'. (B)
  3. Le nombre de documents mot 'w' extérieur temps 't'. (C)
  4. Le nombre de documents sans mot 'w' extérieur temps 't'. (D)

Chacun des éléments ci-dessus représente l'une des cellules d'un tableau de contingence chi-carré pour chaque mot et le temps. Peut tous ces être calculé à l'intérieur d'une seule boucle ou doivent-ils être fait un à la fois?

Idéalement, je voudrais que la sortie soit ce qui est ci-dessous, où a, b, c, d sont tous les éléments calculés ci-dessus:

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

Dans le cas du fichier d'entrée ci-dessus, le résultat d'essayer de trouver la table de contingence pour le mot « pomme » au moment « 1 » serait (3,2,1,6). Je vais vous expliquer comment chaque cellule est calculée:

  • '3' documents contiennent 'pomme' à l'intérieur temps '1'.
  • Il existe des documents '2' dans le temps '1' qui ne contiennent pas 'pomme'.
  • Il est '1' document contenant 'Pomme' de temps à l'extérieur '1'.
  • Il y a 6 documents temps à l'extérieur « 1 » qui ne contiennent pas le mot 'Pomme' (1 + 4 + 1).
Était-ce utile?

La solution

Les 4 chiffres pour la pomme / 1 ajouter jusqu'à 12, plus que le nombre total d'observations (11)! Il n'y a que cinq documents de temps à l'extérieur « 1 » qui ne contiennent pas le mot « pomme ».

Vous devez diviser les observations en 4 sous-ensembles disjoints:
a: pomme et 1 => 3
b: non-pomme et 1 => 2
c: pomme et non-1 => 1
d: non-pomme et non-1 => 5

Voici un code qui montre une façon de le faire:

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)

et est ici la sortie:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top