2013-04-28 1 views
0

나는 세 개의 열 (\ t로 구분 된 파일, 첫 번째 열은 단어, 두 번째는 보조 문자, 세 번째는 태그)가 있습니다. 일부 줄은 점 또는 쉼표로만 구성됩니다.전체 파일의 목록에서 단어 빈도를 계산하는 방법은 무엇입니까?

<doc n=1 id="CMP/94/10"> 
<head p="80%"> 
Customs customs tag1 
union union tag2 
in in tag3 
danger danger tag4 
of of tag5 
the the tag6 
</head> 
<head p="80%"> 
New new tag7 
restrictions restriction tag8 
in in tag3 
the the tag6 
. 
Hi hi tag8 

사용자가 보조 정리 "in"을 검색한다고 가정 해 봅시다. 나는 "in"의 빈도와 "in"의 앞뒤에있는 보조 정리의 빈도를 원합니다. 그래서 나는 전체에 "union", "danger", "restriction"과 "the"의 빈도를 원합니다. 그 결과는 다음과 같아야합니다

union 1 
danger 1 
restriction 1 
the 2 

내가 그걸 어떻게해야합니까?lemma_counter = {}을 사용해 보았지만 작동하지 않습니다.

나는 파이썬 언어에 익숙하지 않으므로, 잘못된 것이 있으면 알려주십시오.

c = open("corpus.vert") 

corpus = [] 

for line in c: 
    if not line.startswith("<"): 
     corpus.append(line) 

lemma = raw_input("Lemma you are looking for: ") 

counter = 0 
lemmas_before_after = []  
for i in range(len(corpus)): 
    parsed_line = corpus[i].split("\t") 
    if len(parsed_line) > 1: 
     if parsed_line[1] == lemma: 
      counter += 1 #this counts lemma frequency 


      new_list = [] 

      for j in range(i-1, i+2): 
       if j < len(corpus) and j >= 0: 
        parsed_line_with_context = corpus[j].split("\t") 
     found_lemma = parsed_line_with_context[0].replace("\n","") 
     if len(parsed_line_with_context) > 1: 
      if lemma != parsed_line_with_context[1].replace("\n",""):       
      lemmas_before_after.append(found_lemma)   
     else: 
      lemmas_before_after.append(found_lemma)     

print "list of lemmas ", lemmas_before_after 


lemma_counter = {} 
for i in range(len(corpus)): 
    for lemma in lemmas_before_after: 
     if parsed_line[1] == lemma: 
      if lemma in lemma_counter: 
       lemma_counter[lemma] += 1 
      else: 
       lemma_counter[lemma] = 1 

print lemma_counter 


fA = counter 
print "lemma frequency: ", fA 

답변

0

이렇게하면 80 %가됩니다.

# Let's use some useful pieces of the awesome standard library 
from collections import namedtuple, Counter 

# Define a simple structure to hold the properties of each entry in corpus 
CorpusEntry = namedtuple('CorpusEntry', ['word', 'lemma', 'tag']) 

# Use a context manager ("with...") to automatically close the file when we no 
# longer need it 
with open('corpus.vert') as c: 
    corpus = [] 
    for line in c: 
     if len(line.strip()) > 1 and not line.startswith('<'): 
      # Remove the newline character and split at tabs 
      word, lemma, tag = line.strip().split('\t') 
      # Put the obtained values in the structure 
      entry = CorpusEntry(word, lemma, tag) 
      # Put the structure in the corpus list 
      corpus.append(entry) 

# It's practical to wrap the counting in a function 
def get_frequencies(lemma): 
    # Create a set of indices at which the lemma occurs in corpus. We use a 
    # set because it is more efficient for the next part, checking if some 
    # index is in this set 
    lemma_indices = set() 
    # Loop over corpus without manual indexing; enumerate provides information 
    # about the current index and the value (some CorpusEntry added earlier). 
    for index, entry in enumerate(corpus): 
     if entry.lemma == lemma: 
      lemma_indices.add(index) 

    # Now that we have the indices at which the lemma occurs, we can loop over 
    # corpus again and for each entry check if it is either one before or 
    # one after the lemma. If so, add the entry's lemma to a new set. 
    related_lemmas = set() 
    for index, entry in enumerate(corpus): 
     before_lemma = index+1 in lemma_indices 
     after_lemma = index-1 in lemma_indices 
     if before_lemma or after_lemma: 
      related_lemmas.add(entry.lemma) 

    # Finally, we need to count the number of occurrences of those related 
    # lemmas 
    counter = Counter() 
    for entry in corpus: 
     if entry.lemma in related_lemmas: 
      counter[entry.lemma] += 1 

    return counter 

print get_frequencies('in') 
# Counter({'the': 2, 'union': 1, 'restriction': 1, 'danger': 1}) 

더 간결하게 (아래) 작성할 수 있으며 알고리즘은 개선 될 수 있습니다 (아직 O (n)이지만). 요점은 그것을 이해할 수있게 만드는 것이 었습니다.

관심이있는 사람들을 위해

:

def get_frequencies(lemma): 
    counter = Counter() 
    related_lemmas = set() 
    for index, entry in enumerate(corpus): 
     counter[entry.lemma] += 1 
     if entry.lemma == lemma: 
      if index > 0: 
       related_lemmas.add(corpus[index-1].lemma) 
      if index < len(corpus)-1: 
       related_lemmas.add(corpus[index+1].lemma) 
    return {lemma: frequency for lemma, frequency in counter.iteritems() 
      if lemma in related_lemmas} 
+0

가 답장을 보내 주셔서 감사 : 여기

with open('corpus.vert') as c: corpus = [CorpusEntry(*line.strip().split('\t')) for line in c if len(line.strip() > 1) and not line.startswith('<')] def get_frequencies(lemma): lemma_indices = {index for index, entry in enumerate(corpus) if entry.lemma == lemma} related_lemmas = {entry.lemma for index, entry in enumerate(corpus) if lemma_indices & {index+1, index-1}} return Counter(entry.lemma for entry in corpus if entry.lemma in related_lemmas) 

을 그리고 약 3 배 빠른 속도로 작동보다 절차 적 스타일입니다. 나는 알아 냈다, 나의 파일은 내가 예상했던 정확하게 것이 아니다. 일부 줄은 점 또는 쉼표로만 구성되어 있으므로 튜플이 작동하지 않습니다. 'len (line)> 1 :'인 경우 line.startswith ('<') :' '인 경우이 오류를 시도했지만 "아직 압축을 풀려면 1 개 이상의 값이 필요합니다"라는 오류가 발생합니다. – halik

+0

@halik 모든'line'은'corpus'에 추가되기 전에 줄 문자 ('\ n')를 포함하기 때문에 처음에는'line'의 길이가 1보다 커야합니다. 내 대답을 조정했다. –

관련 문제