class _FakeMecabNode:
def __init__(self, surface, feature, is_eos=False):
self.surface = surface
self.feature = feature
self.is_eos = lambda: is_eos
@pytest.mark.parametrize(
('text', 'tokens', 'whitespaces', 'is_spaces'),
[
('', [], [], []),
(' ', [' '], [''], [True]),
('A', ['A'], [''], [False]),
('A ', ['A', ' '], ['', ''], [False, True]),
(' A', [' ', 'A'], ['', ''], [True, False]),
(
' A B ',
[' ', 'A', 'B', ' '],
['', ' ', '', ''],
[True, False, False, True],
),
(
' \n Hello \n\n \n great\n\nworld !\n\n',
[
' \n ',
'Hello',
' \n\n \n ',
'great',
'\n\n',
'world',
'!',
'\n\n',
],
['', ' ', '', '', '', ' ', '', ''],
[True, False, True, False, True, False, False, True],
),
],
)
@patch(
'spacy.lang.ko.try_mecab_import',
Mock(
return_value=lambda _: Mock(
parse=lambda text, as_nodes: [
_FakeMecabNode(x, 'A,B,C/D/E') for x in text.split()
]
+ [_FakeMecabNode('', '', True)]
)
),
)
def test_custom_korean_tokenizer(text, tokens, whitespaces, is_spaces):
doc = _CustomKoreanTokenizer(
spacy.vocab.create_vocab('ko', spacy.language.BaseDefaults)
)(text)
assert text == doc.text
assert tokens == [x.text for x in doc]
assert whitespaces == [x.whitespace_ for x in doc]
assert is_spaces == [x.is_space for x in doc]
When tokenizing Korean text, the tokenizer loses information about complex whitespace by replacing them with a single space. Consequently,
textis not equal tonlp(text).text. This discrepancy causes a problem: entities described in the original text with(start, end)indices no longer align with those in the tokenized document. Similarly, the offsets of predicted entities do not match those in the original text.The described issue, for example, invalidates this code:
How to reproduce the behaviour
Suggested solution
I presume it might not be the most correct/idiomatic/optimized solution but at least it works for my case (named entity recognition).
This is how I solved the issues for my project:
Tests for the solution:
Your Environment