我有一些推文,我希望将其拆分成单词。大部分功能都可以正常工作,除非人们组合使用以下单词:trumpisamoron
或 makeamericagreatagain
。但还有一些诸如 password
之类的内容不应分为 pass
和 word
。
我知道 nltk 包有一个 punkt tokenizer
模块,它以智能的方式分割句子。词有类似的东西吗?即使它不在 nltk 包中?
注意:password -> pass + word
的示例比拆分单词问题问题要小得多。
最佳答案
引用:我对另一个问题的回答 - 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
词典中的可能性可能会更高。
在最后一段中,它将 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']
为了获得比这更好的解决方案,您可以使用二元组/三元组。
关于python - 边界上的拆分词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39781936/