2013-05-28 4 views
0

У меня есть .txt файл (пример):Счетные слова в текстовом файле

Профессиональный человек, который занимается определенной деятельностью, или занятие, для усиления или компенсации в качестве средств к существованию; такой как постоянная карьера , а не как любитель или времяпрепровождение. Из-за личного и конфиденциального характера многих профессиональных услуг, и, следовательно, необходимости вложить в них большое доверие, большинство профессионалов подвергаются строгим кодам поведения, строящим этические моральные обязательства и моральным обязательствам .

Как подсчитать, сколько раз есть слово «профессионал»? (С использованием NLTK - это лучший вариант?)

text_file = open("text.txt", "r+b") 
+0

Что вы пробовали? Взгляните на http://www.daniweb.com/software-development/python/code/216495/wordcount-of-a-text-file-python - может быть полезно – Smajl

+0

Вы хотите посчитать «профессионалы» как экземпляр? Что относительно 'Professional', или' professional, '? Или 'prof-' в конце строки с 'essional' на следующем? Пока вы не определите проблему, вы не сможете ее решить. – abarnert

+0

Кроме того, почему вы открываете файл в режиме 'r + b'? Если вы не хотите писать на него, не добавляйте '+'. Если вы не хотите вручную обрабатывать разные типы строк, наборов символов и т. Д., Не добавляйте 'b'. – abarnert

ответ

3

Я изменил свой ответ, чтобы лучше отражать ваши пожелания:

from nltk import word_tokenize 

with open('file_path') as f: 
    content = f.read() 
# we will use your text example instead: 
content = "A professional is a person who is engaged in a certain activity, or occupation, for gain or compensation as means of livelihood; such as a permanent career, not as an amateur or pastime. Due to the personal and confidential nature of many professional services, and thus the necessity to place a great deal of trust in them, most professionals are subject to strict codes of conduct enshrining rigorous ethical and moral obligations." 

def Count_Word(word, data): 
    c = 0 
    tokens = word_tokenize(data) 
    for token in tokens: 
     token = token.lower() 
     # this plural check is dangerous, if trying to find a word that ends with an 's' 
     token = token[:-1] if token[-1] == 's' else token 
     if token == word: 
      c += 1 
    return c 

print Count_Word('professional', content) 
>>> 
3 

Вот модифицированная версия метода:

def Count_Word(word, data, leading=[], trailing=["'s", "s"]): 
    c = 0 
    tokens = word_tokenize(data) 
    for token in tokens: 
     token = token.lower() 
     for lead in leading: 
      if token.startswith(lead): 
       token = token.partition(lead)[2] 
     for trail in trailing: 
      if token.endswith(trail): 
       token = token.rpartition(trail)[0] 
     if token == word: 
      c += 1 
    return c 

Я добавил к необязательным аргументам, которые представляют собой списки ведущих или конечных частей слова, которые вы хотите обрезать, чтобы найти его ... На e моментом я ставлю только по умолчанию 's или s. Но если вы обнаружите, что другие подойдут вам, вы всегда сможете их добавить. Если списки начнут длиться, вы можете сделать их константами.

+1

Если вы хотите только сосчитать экземпляры 'professional', то создание« Counter »со всеми уникальными словами 5000 - это немного, чем немного расточительно. Кроме того, я не уверен, как вы собираетесь делать эту работу с нечеткой синхронизацией, о которой явно просил OP. – abarnert

+0

Почему downvote? - @abarnert Когда я ответил на вопрос, OP не прокомментировал, что он хочет нечеткое совпадение, но я все же отредактировал свой ответ, чтобы включить упоминание об этом. Этот вопрос касается подсчета слов, а не нечеткого соответствия. Если OP хочет спросить новый вопрос о том, как нечеткое совпадение ... он может это сделать ... Изменение вопроса, пока есть ответы на тот, который вы изначально задали, сбивает с толку и нахмурился здесь (как я уверен, вы знаете) –

+0

I не знаю, кто его ниспровергал (или почему они не уменьшали полудюжины почти идентичных ответов), но я предполагаю, что кто-то согласился с одним из моих двух комментариев. Во-первых, вы не дали ответа. Во втором случае добавленное вами добавление в основном «Этот код не будет работать, но многие другие методы могут», что на самом деле не помогает. И, учитывая, что ОП задал вопрос об использовании NLTK в исходной версии вопроса, это подразумевает, что он, по крайней мере, думал о таких случаях, как 'professional.', поэтому он только уточнил вопрос, а не изменил его. – abarnert

3

Вы могли бы просто разметить строку, а затем искать все маркеры ... но это только один из способов. Есть много других ...

s = text_file.read() 
tokens = nltk.word_tokenize(s) 
counter = 0 
for token in tokens: 
    toke = token 
    if token[-1] == "s": 
    toke = token[0:-1] 
    if toke.lower() == "professional": 
    counter += 1 

print counter 
1
from collections import Counter 

def stem(word): 
    if word[-1] == 's': 
     word = word[:-1] 
    return word.lower() 

print Counter(map(stem, open(filename).read().split())) 
3

Может быть решен в одной строке (плюс импорт):

>>> from collections import Counter 
>>> Counter(w.lower() for w in open("text.txt").read().split())['professional'] 
2 
+0

Хорошо, требования изменены позже, что делает это решение в настоящее время неадекватным по назначению. –

1

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

В приведенном ниже коде я определил три функции, которые возвращают словарь отсчетов для всех слов, входящих в текст ввода.

import nltk 
from collections import defaultdict 

text = "This is my sample text." 

lower = text.lower() 

tokenized = nltk.word_tokenize(lower) 

ps = nltk.stem.PorterStemmer() 
wnlem = nltk.stem.WordNetLemmatizer() 

# The Porter stemming algorithm tries to remove all suffixes from a word. 
# There are better stemming algorithms out there, some of which may be in NLTK. 
def StemCount(token_list): 
    countdict = defaultdict(int) 
    for token in token_list: 
     stem = ps.stem(token) 
     countdict[stem] += 1 
    return countdict 

# Lemmatizing is a little less brutal than stemming--it doesn't try to relate 
# words across parts of speech so much. You do, however, need to part of speech tag 
# the text before you can use this approach. 
def LemmaCount(token_list): 
    # Where mytagger is a part of speech tagger 
    # you've trained (perhaps per http://nltk.sourceforge.net/doc/en/ch03.html) 
    # using a simple tagset compatible with WordNet (i.e. all nouns become 'n', etc) 
    token_pos_tuples = mytagger.tag(token_list) 
    countdict = defaultdict(int) 
    for token_pos in token_pos_tuples: 
     lemma = wnlem.lemmatize(token_pos[0],token_pos[1]) 
     countdict[lemma] += 1 

# Doesn't do anything fancy. Just counts the number of occurrences for each unique 
# string in the input. 
def SimpleCount(token_list): 
    countdict = defaultdict(int) 
    for token in token_list: 
     countdict[token] += 1 
    return countdict 

В качестве примера различия между PorterStemmer и WordNetLemmatizer, необходимо учитывать следующее:

>>> wnlem.lemmatize('professionals','n') 
'professional' 
>>> ps.stem('professionals') 
'profession' 

с wnlem и пс, как определено в приведенном выше фрагменте кода.

В зависимости от вашего приложения, что-то вроде SimpleCount (token_list) может работать нормально.

Смежные вопросы