之前已经有一个提问了: https://www.v2ex.com/t/340752#reply13
关于这个问题搜索了挺久还不是很明白,于是开了这个帖子。
我想做英文词组分词(可能不这么叫),比如 I love New York,我希望分词出来的是 I / love / New York,而不是:I / love / New / York 。New York 分开原本的意思就变了。
中文分词有非常多的工具,比如结巴( https://github.com/fxsjy/jieba ),但是找英文词组分词工具就非常难(我甚至不知道用什么单词去搜索,比如是 Tokenizer 、Chunking 、还是 text segmentation ),请问英文有没有比较方便可以直接分词的工具。
比如斯坦福的 stanza ( https://github.com/stanfordnlp/stanza ) 可以用于分词。中文分词结果没问题,但是英文只是按照空格做分词。
text = """英国首相约翰逊 6 日晚因病情恶化。"""
zh_nlp = stanza.Pipeline('zh')
doc = zh_nlp(text)
for sent in doc.sentences:
print("Sentence:" + sent.text) # 断句
print("Tokenize:" + ' '.join(token.text for token in sent.tokens)) # 中文分词
它的输出结果是分词后的结果,这没问题:
Tokenize:英国 首相 约翰逊 6 日 晚因 病情 恶化 , 被 转入 重症 监护 室 治疗 。
但是英文分词:
import stanza
nlp = stanza.Pipeline(lang='en', processors='tokenize', tokenize_no_ssplit=True)
doc = nlp('This is a sentence.\n\nThis is a second. This is a third.')
for i, sentence in enumerate(doc.sentences):
print(f'====== Sentence {i+1} tokens =======')
print(*[f'id: {token.id}\ttext: {token.text}' for token in sentence.tokens], sep='\n')
输出结果为:
====== Sentence 1 tokens =======
id: (1,) text: This
id: (2,) text: is
id: (3,) text: a
id: (4,) text: sentence
id: (5,) text: .
====== Sentence 2 tokens =======
id: (1,) text: This
id: (2,) text: is
id: (3,) text: a
id: (4,) text: second
id: (5,) text: .
id: (6,) text: This
id: (7,) text: is
id: (8,) text: a
id: (9,) text: third
id: (10,) text: .
1
heiheidewo 2020-11-16 21:13:53 +08:00
自己写一个吧,一般分词是按双向最长匹配来的,你把 New York 当做一个词处理即可
|
2
TimePPT 2020-11-16 21:21:10 +08:00 via Android
没明白,你举的 stanza 用 en pipeline 分出来哪里不对吗?
|
3
chizuo 2020-11-16 21:31:29 +08:00
可以试试 nltk/spacy 这类库,一般以 word-level 为级别的分词,很难避免你说的这个问题。你可以试试 sub-word level 以及结合 named entity 、pos_tag 这类判断
以 nlp tokenizer segmenter 为关键词看看相关论文 |
4
BarryLu OP @TimePPT 想说的是,Stanza 的英文分词只是按照空格分开的,但是中文是 “真正分词”。另外比如 Tensorflow Keras 的英文分词( Tokenizer )也只是按照空格分开,现成的,做到类似于中文分词的「英文分词」工具,没找到。。。
|
5
BarryLu OP @heiheidewo 自己写 😭 很有难度。另外如果需要处理一大批数据,我也不知道里面到底有多少「名词」不应该分开。
|
6
TimePPT 2020-11-16 22:25:39 +08:00 via Android
@BarryLu 很难做,LS 也提到了,通过 NER 之类的可以做到一部分,或者直接拿词典匹配。但没法完全避免。
另外,其实中文分词颗粒度问题更难,根据业务需要要微调的。 |
7
mxalbert1996 2020-11-16 22:52:37 +08:00 via Android
英文里这种情况本来就很少,其中很大一部分都是专有名词,其实没太大影响,而且现在 NLP 都是 RNN,能识别前后关系,就更无所谓了。
|
8
jhdxr 2020-11-16 23:04:37 +08:00
其实你要的并不是分词,比如 I want to have a cup of green apple juice.
在你定义的『分词』中,green apple juice 是一个『词』还是多个词? 如果你认为那是一个词,那你可以考虑 syntax parsing 如果你认为那是多个词,那我猜你想要的其实是识别专有名词(请尝试分词中文:『南京市长江大桥』),可以考虑 NER/NEM |
9
Merlini 2020-11-16 23:16:00 +08:00
这种一般是需要知识图谱辅助的,或者就直接用训练好的 NER 。比如 Spacy 的 NER:
```python import spacy nlp = spacy.load("en_core_web_sm") doc = nlp("Apple is looking at buying U.K. startup for $1 billion") for ent in doc.ents: print(ent.text, ent.start_char, ent.end_char, ent.label_) ``` https://spacy.io/usage/linguistic-features#named-entities-101 |
10
yucongo 2021-01-05 15:23:34 +08:00
不知道楼主有没有找到解决方法?找到了话能不能分享一下?
如果只是对名词词组感兴趣,spacy/textaxy/textblob 里的 noun_chunks/noun phrases/NER 或许有用。但我也是希望能像 jieba 做中文分词那样将英语句子分成有意义的词组,例如:A match / is / a tool / for starting / a fire. Typically, / modern matches / are made of / small wooden sticks or stiff paper. 搜了一下,好像没有现成的工具,最接近的办法可能是用 spacy 的 rule based matching 匹配出 noun phrase (比较简单,有现成的)和 verb phrase 。textacy 里有个极简的 VP 常数('<AUX>* <ADV>* <VERB>')。 总之,离英语“词组分词”还很远 |