如何解决诸如T&C之类的标记化短语不被拆分为'T''&''C'

时间:2019-07-03 12:58:28

标签: python-3.x nlp nltk

我正在尝试清理一些文本数据,以准备使用NLP技术。我要求保留诸如T&C和S&P之类的模式。但是,当我对句子进行标记时,它会被分成“ T”,“&”,“ C”而不是“ T&C”。

我已经尝试寻找该规则的豁免,但找不到给定任何顺序(例如FT&P或S&ST或S&T)的通用方法来完成此操作

import pandas as pd

from nltk import word_tokenize, pos_tag
from nltk.corpus import stopwords


en_stop = set(stopwords.words('english'))
en_stop = [word for word in en_stop]
[en_stop.append(x) for x in ['shall', 'should','please']]

def rem_stopwords(txt):
    words = [w for w in word_tokenize(txt) if w not in en_stop]
    return " ".join(words)

rem_stopwords('what is f&p doing in regards')
Out[163]: ['f', '&', 'p', 'regards']

我希望输出为['f&p','regards']

2 个答案:

答案 0 :(得分:3)

NLP系统随附的令牌生成器有时非常基本,甚至高级的 以您可能不喜欢的特定方式处理某些极端情况。

底线:您有几个选择:

  • 找到可以完全满足您需求的现成解决方案。

  • 查找可调整设置以执行所需操作的设置或配置。斯坦福nltk有 多种变体,例如随便,MWETokenizer,nist和punkt,以及一些选项 就像将自己的正则表达式添加到其中一些正则表达式一样(请参见https://www.nltk.org/api/nltk.tokenize.html)。

  • 编写代码以更改现有解决方案(如果它是开源的,则可以更改代码 本身;许多系统还具有API,可让您覆盖某些部分 而不是深入挖掘胆量。

  • 从头开始编写令牌生成器(这比看上去要难得多)。

  • 对数据进行预处理或后处理以解决特定问题。

但是&符可能不是您遇到的唯一情况。我建议 依次经历每个标点符号,并花一分钟 考虑当它出现时想要发生什么。那你就更清楚了 评估您的选择时要记住的一组目标。例如:

“&”-也会显示在网址中,请注意“<”如果要解析HTML,则为“ &&”(如果解析代码)。

“ /”-您可能不想在每个斜杠上标记URL(当然也不想像语法一样尝试解析结果标记!)。还有12/31 / 2019、1 / 2和更多案例。

“-”-连字符高度不明确:-1、12-4,子句级破折号的双连字符(以及某些代码中的减量运算符),行尾连字符(可能或可能不(希望将其关闭),长串的连字符作为分隔线。

行情-卷曲或直线,单引号和撇号表示收缩或所有格(或错误地表示复数),等等。

Unicode引入了各种情况,例如不同类型的空格,引号和破折号。许多编辑器喜欢将它们自动纠正为Unicode字符,甚至是小数:1/2可能会以单个字符结尾(您是否希望令牌生成器将其分成3个令牌?)。

编写一小套测试用例并进行尝试非常容易(而且恕我直言,这是非常有用的练习)。某些现有的令牌生成器可以在线试用,例如:

斯坦福[corenlp:http://corenlp.run/]

Python NLTK:[https://text-processing.com/demo/tokenize/]

Spacy:[http://textanalysisonline.com/spacy-word-tokenize]

MorphAdorner:[http://morphadorner.northwestern.edu/morphadorner/wordtokenizer/example/]

这只是一个小样本-还有许多其他样本,其中一些样本有多种选择。

如果您只想为这种情况提供一种真正快捷的解决方案,则可以对令牌列表进行后处理以重新合并有问题的案例,或对其进行预处理以使其变成r'\ w&\ w'变成一些令牌化器不会分解的魔术字符串,然后再将其返回。这些几乎都是骇客,但在有限的情况下它们可能还可以。

答案 1 :(得分:0)

如果最适合您的数据,则可以使用拆分功能代替word_tokenize,但是根据示例文本,拆分功能可以为您完成工作

  def rem_stopwords(txt, en_stop):
     words = [w for w in txt.split() if w not in en_stop]
     return " ".join(words)

 #o/p
 rem_stopwords('what is f&p doing in regards', en_stop)
 'f&p regards'