2016-09-30 7 views
1

単語に分割したいつぶやきがあります。多くの人は、人々がtrumpisamoronmakeamericagreatagainのような単語を組み合わせている場合を除いて正常に動作します。しかし、passwordに分割してはならないpasswordのようなものもあります。境界に単語を分割する

nltkパッケージには、文をスマートに分割するpunkt tokenizerモジュールがあります。言葉に似たものがありますか?たとえそれがnltkパッケージに含まれていないとしても?

注:password -> pass + wordの例は、分割語の問題よりもはるかに問題になりません。

+2

は、彼らが別々に扱われるべきである(それはちょうど私の個人的な意見だ – alvas

+1

ない、これは任意の助けのですが、あなたが得ることができること。 – Corgs

+1

これは絶対的なブルートフォースの解決策になるでしょう(そしてかなりのコンピューティングパワーがかかるでしょう)が、あなたはフレーズ 'trumpisamoron'を検索し、その文字列内の単語のすべての可能な順列を実行し、各単語の出現の可能性を' word:frequency'のキーと値の対の辞書と比較します。 、「tru」、「trum」、または「trump」は、言葉私はこのソリューションをお勧めしませんが、あなたのデータのサイズに応じて、それは実行可能かもしれません。 – blacksite

答えて

1

Ref:別の質問の回答 - Need to split #tags to text

この回答の変更点は(1)WORDSを取得するためのコーパスと(2)処理を高速化するためにdef memo(f)を追加しました。あなたが作業しているドメインに応じてコーパスを追加/使用する必要があるかもしれません。

チェック - 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辞書に存在しないという高いチャンスがあるかもしれません。

ここで最後のセグメントでは、トークンidiotsWORDSに存在しなかったため、narcisticidiotsが3つのトークンに分割されました。

# 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を使用できます。で

より多くの例:あなたは `#のhashtags`で作業している場合Word Segmentation Task

関連する問題