2016-09-30 2 views
1

У меня есть некоторые твиты, которые я хочу разделить на слова. Большинство из них прекрасно работает, за исключением случаев, когда люди объединяют слова типа: trumpisamoron или makeamericagreatagain. Но тогда есть такие вещи, как password, которые не следует разделить на pass и word.Разделить слова на границе

Я знаю, что в пакете nltk есть модуль punkt tokenizer, который расщепляет предложения в интеллектуальном виде. Есть ли что-то подобное для слов? Даже если это не в пакете nltk?

Примечание: Пример password -> pass + word представляет собой гораздо меньшую проблему, чем проблема слова разбиения.

+2

, если вы работаете с '# hashtags', они должны рассматриваться по-разному (но это только мое личное мнение – alvas

+1

не то, что это какой-либо помощи, но вы могли бы получить. текстовый файл всех слов на английском языке и сравнение твитов со словами. Далеко не 100% точная. – Corgs

+1

Это было бы абсолютное решение для грубой силы (и, вероятно, потребовало бы значительной вычислительной мощности), но вы могли бы воспользоваться фраза 'trumpisamoron' и запускать все возможные перестановки слов в этой строке и сравнивать вероятность каждого слова в зависимости от словаря пар ключ-значение слова: частота. Это в основном означает, что вы проверите, какой из' t', 'tr' , 'tru',' trum' или 'trump', скорее всего, будет слово. Я бы не рекомендовал это решение, но в зависимости от размера ваших данных это могло бы быть выполнимым. – blacksite

ответ

1

Ref: Мой ответ на другой вопрос - Need to split #tags to text.

Изменения в этом ответе, которые я сделал, - (1) Различные корпуса для получения WORDS и (2) Добавлены def memo(f) для ускорения процесса. Возможно, вам потребуется добавить/использовать корпус в зависимости от домена, над которым вы работаете.

Check - Word Segmentation Task от Norvig Работа.

from __future__ import division 
from collections import Counter 
import re, nltk 
from datetime import datetime 

WORDS = nltk.corpus.reuters.words() + nltk.corpus.words.words() 
COUNTS = Counter(WORDS) 

def memo(f): 
    "Memoize function f, whose args must all be hashable." 
    cache = {} 
    def fmemo(*args): 
     if args not in cache: 
      cache[args] = f(*args) 
     return cache[args] 
    fmemo.cache = cache 
    return fmemo 

def pdist(counter): 
    "Make a probability distribution, given evidence from a Counter." 
    N = sum(counter.values()) 
    return lambda x: counter[x]/N 

P = pdist(COUNTS) 

def Pwords(words): 
    "Probability of words, assuming each word is independent of others." 
    return product(P(w) for w in words) 

def product(nums): 
    "Multiply the numbers together. (Like `sum`, but with multiplication.)" 
    result = 1 
    for x in nums: 
     result *= x 
    return result 

def splits(text, start=0, L=20): 
    "Return a list of all (first, rest) pairs; start <= len(first) <= L." 
    return [(text[:i], text[i:]) 
      for i in range(start, min(len(text), L)+1)] 

@memo 
def segment(text): 
    "Return a list of words that is the most probable segmentation of text." 
    if not text: 
     return [] 
    else: 
     candidates = ([first] + segment(rest) 
         for (first, rest) in splits(text, 1)) 
     return max(candidates, key=Pwords) 

print segment('password')  # ['password'] 
print segment('makeamericagreatagain')  # ['make', 'america', 'great', 'again'] 
print segment('trumpisamoron')  # ['trump', 'is', 'a', 'moron'] 
print segment('narcisticidiots')  # ['narcistic', 'idiot', 's'] 

Иногда, в случае, слово получает пролитой в меньший знак, может быть выше вероятность того, что слово нет в нашем WORDS словаре.

Здесь в последнем сегменте он разбил narcisticidiots на 3 жетона, потому что токен idiots не был в нашем WORDS.

# Check for sample word 'idiots' 
if 'idiots' in WORDS: 
    print("YES") 
else: 
    print("NO") 

Вы можете добавить новые пользовательские слова WORDS.

. 
. 
user_words = [] 
user_words.append('idiots') 

WORDS+=user_words 
COUNTS = Counter(WORDS) 
. 
. 
. 
print segment('narcisticidiots')  # ['narcistic', 'idiots'] 

Для лучшего решения, чем это, вы можете использовать bigram/trigram.

Другие примеры по адресу: Word Segmentation Task