Концептуальное - Как построить двумерную словесно-частотную матрицу в Python? - PullRequest
1 голос
/ 12 марта 2012

Я пытаюсь применить технику логистической регрессии для категоризации текста, и я хочу построить набор данных в виде матрицы apxn, p строк для воспроизведения и n столбцов для уникальных слов.У меня уже есть текст для работы, мне просто нужно посчитать слова в нем.

Важно отслеживать, какое слово встречается в игре, поэтому для данной игры я смог создатьсловарь Python, который подсчитывает уникальные слова.Что я не знаю, как это сделать, так это объединить эти дикты, чтобы, например,

romeo = {[alas,2],[julliet,35]}
caesar = {[et,1],[tu,3],[cassius,12]}

можно было объединить, чтобы получить матрицу

      alas  julliet  et  tu cassius
romeo  2        35    0   0  0 
caesar 0        0     1   3  12

.где каждая пьеса состоит только из уникальных слов - естественно, на самом деле это совсем не так.

Как можно было бы построить эту матрицу из этих словарей?Будет ли легче начать откуда-то еще?

Ответы [ 3 ]

1 голос
/ 12 марта 2012

Работает, проверено:

from itertools import chain
from collections import defaultdict

romeo = {'alas':2, 'juliet':35, 'hello':1}
caesar = {'et':1, 'tu':3, 'cassius':12, 'hello':1}

dicts = defaultdict(dict)
dicts['romeo'] = romeo
dicts['caesar'] = caesar

columns = list(set(list(chain(romeo.keys(), caesar.keys()))))

matrix = defaultdict(dict)

for coll in ('romeo', 'caesar'):
    matrix[coll] = {}
    for key in columns:
        if dicts[coll].has_key(key):
            matrix[coll][key] = dicts[coll][key]
        else:
            matrix[coll][key] = 0

print columns

for coll in matrix.keys():
    for key in columns:
        print matrix[coll][key], 
    print '\n'

Объяснение: объедините все ключи из обоих словарей вместе, затем запустите циклы и введите совершенно новый диктат :):

0 голосов
/ 15 марта 2012

В конце концов, я закончил тем, что реализовал defaultdict, потому что мне понравилось, как он будет создавать словари или словарные записи (в зависимости от местоположения), когда ссылка ранее не существовала.

Я построилполный defaultdict с тем, что я хотел, а затем громко выводить в CSV.

Я использовал полный текстовый дамп с opensourceshakespeare.com, вот что я написал:

    playNames = {}

    for line in listOfLines:
            try:
                    playNames[line.rsplit('~')[0]] += 1
                    if line.rsplit('~')[0] == '':
                        print line
            except:
                    playNames[line.rsplit('~')[0]] = 1

    #print playNames.keys()

    #
    # Now let's build a dictionary for each play
    #

    for line in listOfLines:

            try:
                    playNames[line.rsplit('~')[0]] += line.rsplit('~,~')[2]
                    playNames[line.rsplit('~')[0]] += " "
            except:
                    playNames[line.rsplit('~')[0]] = line.rsplit('~,~')[2]
                    playNames[line.rsplit('~')[0]]+= " "

    #
    # for each play, tokenize text into list of words
    #

    for key in playNames.iterkeys():
            playNames[key] = playNames[key].split(' ')

    plays = collections.defaultdict(dict)

    for key in playNames.iterkeys():
            for val in playNames[key]:
                    try:
                            plays[key][val] += 1
                    except:
                            plays[key][val] = 1

    #
    # build a set of words
    #

    words = set()

    for eachplay in plays.itervalues():
            words.update(eachplay.keys())

    outfile = open("wordlist.csv",'w')

    i=0
    outfile.write(",")
    for word in words:

            outfile.write(word)
            outfile.write(",")
            i+=1
    print "words ",i

    outfile.write("\n")
    for eachplay in plays.iterkeys():
            i = 0
            outfile.write(eachplay)

            outfile.write(",")
            for word in words:
                    try:
                            outfile.write(str(plays[eachplay].get(word,"0")))
                            #print word,plays[eachplay][word]
                    except:
                         outfile.write("")
                    i+=1
                    outfile.write(",")
            outfile.write("\n")
            print eachplay," ",i
    outfile.close()
0 голосов
/ 12 марта 2012

Я бы использовал вложенные словари или двумерные словари.Для вложенных, во-первых, вам нужно изменить формат вашего диктитона на правильную форму:

romeo = {[alas,2],[julliet,35]}
caesar = {[et,1],[tu,3],[cassius,12]}

должно быть:

romeo = {'alas':2,'julliet': 35}
caesar = {'et':1,'tu':3,'cassius':12}

Оттуда вы можете перебрать все«значения» в словаре и вложенные словари, так что вместо матрицы, как у вас есть, вы можете иметь что-то вроде:

#declare first:
Ds = {{}}

Затем используйте цикл для заполнения:

Ds = {
      'romeo' : {'et': 0, 'alas':2,'julliet': 35, tu':0,'cassius':0}, 
      'caesar' :  {'et':1, 'alas':0, 'julliet': 0, 'tu':3,'cassius':12}
      }

Надеюсь, это поможет.

...