Git Product home page Git Product logo

razdel's Introduction

CI

razdel — rule-based system for Russian sentence and word tokenization.

Usage

>>> from razdel import tokenize

>>> tokens = list(tokenize('Кружка-термос на 0.5л (50/64 см³, 516;...)'))
>>> tokens
[Substring(0, 13, 'Кружка-термос'),
 Substring(14, 16, 'на'),
 Substring(17, 20, '0.5'),
 Substring(20, 21, 'л'),
 Substring(22, 23, '(')
 ...]
 
>>> [_.text for _ in tokens]
['Кружка-термос', 'на', '0.5', 'л', '(', '50/64', 'см³', ',', '516', ';', '...', ')']
>>> from razdel import sentenize

>>> text = '''
... - "Так в чем же дело?" - "Не ра-ду-ют".
... И т. д. и т. п. В общем, вся газета
... '''

>>> list(sentenize(text))
[Substring(1, 23, '- "Так в чем же дело?"'),
 Substring(24, 40, '- "Не ра-ду-ют".'),
 Substring(41, 56, 'И т. д. и т. п.'),
 Substring(57, 76, 'В общем, вся газета')]

Installation

razdel supports Python 3.7+ and PyPy 3.

$ pip install razdel

Documentation

Materials are in Russian:

Evaluation

Unfortunately, there is no single correct way to split text into sentences and tokens. For example, one may split «Как же так?! Захар...» — воскликнут Пронин. into three sentences ["«Как же так?!", "Захар...»", "— воскликнут Пронин."] while razdel splits it into two ["«Как же так?!", "Захар...» — воскликнут Пронин."]. What would be the correct way to tokenizer т.е.? One may split in into т.|е., razdel splits into т|.|е|..

razdel tries to mimic segmentation of these 4 datasets: SynTagRus, OpenCorpora, GICRYA and RNC. These datasets mainly consist of news and fiction. razdel rules are optimized for these kinds of texts. Library may perform worse on other domains like social media, scientific articles, legal documents.

We measure absolute number of errors. There are a lot of trivial cases in the tokenization task. For example, text чуть-чуть?! is not non-trivial, one may split it into чуть|-|чуть|?|! while the correct tokenization is чуть-чуть|?!, such examples are rare. Vast majority of cases are trivial, for example text в 5 часов ... is correctly tokenized even via Python native str.split into в| |5| |часов| |.... Due to the large number of trivial case overall quality of all segmenators is high, it is hard to compare differentiate between for examlpe 99.33%, 99.95% and 99.88%, so we report the absolute number of errors.

errors — number of errors per 1000 tokens/sentencies. For example, consider etalon segmentation is что-то|?, prediction is что|-|то?, then the number of errors is 3: 1 for missing split то? + 2 for extra splits что|-|то.

time — seconds taken to process whole dataset.

spacy_tokenize, aatimofeev and others a defined in naeval/segment/models.py, for links to models see Naeval registry. Tables are computed in naeval/segment/main.ipynb.

Tokens

corpora syntag gicrya rnc
errors time errors time errors time errors time
re.findall(\w+|\d+|\p+) 24 0.5 16 0.5 19 0.4 60 0.4
spacy 26 6.2 13 5.8 14 4.1 32 3.9
nltk.word_tokenize 60 3.4 256 3.3 75 2.7 199 2.9
mystem 23 5.0 15 4.7 19 3.7 14 3.9
mosestokenizer 11 2.1 8 1.9 15 1.6 16 1.7
segtok.word_tokenize 16 2.3 8 2.3 14 1.8 9 1.8
aatimofeev/spacy_russian_tokenizer 17 48.7 4 51.1 5 39.5 20 52.2
koziev/rutokenizer 15 1.1 8 1.0 23 0.8 68 0.9
razdel.tokenize 9 2.9 9 2.8 3 2.0 16 2.2

Sentences

corpora syntag gicrya rnc
errors time errors time errors time errors time
re.split([.?!…]) 114 0.9 53 0.6 63 0.7 130 1.0
segtok.split_single 106 17.8 36 13.4 1001 1.1 912 2.8
mosestokenizer 238 8.9 182 5.7 80 6.4 287 7.4
nltk.sent_tokenize 92 10.1 36 5.3 44 5.6 183 8.9
deeppavlov/rusenttokenize 57 10.9 10 7.9 56 6.8 119 7.0
razdel.sentenize 52 6.1 7 3.9 72 4.5 59 7.5

Support

Development

Dev env

python -m venv ~/.venvs/natasha-razdel
source ~/.venvs/natasha-razdel/bin/activate

pip install -r requirements/dev.txt
pip install -e .

Test

make test
make int  # 2000 integration tests

Release

# Update setup.py version

git commit -am 'Up version'
git tag v0.5.0

git push
git push --tags

mystem errors on syntag

# see naeval/data
cat syntag_tokens.txt | razdel-ctl sample 1000 | razdel-ctl gen | razdel-ctl diff --show moses_tokenize | less

Non-trivial token tests

pv data/*_tokens.txt | razdel-ctl gen --recall | razdel-ctl diff space_tokenize > tests.txt
pv data/*_tokens.txt | razdel-ctl gen --precision | razdel-ctl diff re_tokenize >> tests.txt

Update integration tests

cd tests/data/
pv sents.txt | razdel-ctl up sentenize > t; mv t sents.txt

razdel and moses diff

cat data/*_tokens.txt | razdel-ctl sample 1000 | razdel-ctl gen | razdel-ctl up tokenize | razdel-ctl diff moses_tokenize | less

razdel performance

cat data/*_tokens.txt | razdel-ctl sample 10000 | pv -l | razdel-ctl gen | razdel-ctl diff tokenize | wc -l

razdel's People

Contributors

9dogs avatar averkij avatar inthedark122 avatar kuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

razdel's Issues

Токенизация не объединяет сокращения

Заметил что в tokenize нет RULE которое бы объединило сокращение в один терм, это было сделано специально?

Такое правило добавлено в sentenize, что привело к различному формированию токенов

Что бы добавить дополнительное правило необходимо полностью переписать TokenSegmenter, можно дать возможность передавать аргументы как это было сделано для SentSegmenter ?

Правильное разбиение числовых диапазонов

Здравствуйте.
Токенизатор правильно разбивает тексты, где содержатся названия городов:
Ростов-на-Дону Санкт-Петербург

Однако с диапазонами значений он поступает аналогично:
2016-2017 - один токен
5-кратное - один токен
10ти-кратное - разбивается на 10 и ти-кратное

Эвристическими правилами удаляются правильные разделения предложений

Следующие пары предложений расцениваются как одно:
Точка K принадлежит отрезку MN длиной 32 см и делит его в отношении 3:5, считая от точки M. Найдите KM.
Точка К принадлежит отрезку АВ длиной 3 и делит его в отношении 2:7 считая от точки А. Найдите КВ.

Мешает то ли римская M как перечислимый пункт, то ли инициалы, то ли еще что...

StopIteration Error python3.7

Здравствйте, столкнулся со следующей проблемой при использовании на python 3.7.
Там необходимо немного переписать обращение к генератору, как, например, тут https://stackoverflow.com/questions/51700960/runtimeerror-generator-raised-stopiteration-every-time-i-try-to-run-app

Вот так выглядит traceback в данный момент.

File "/usr/lib/python3.7/site-packages/razdel/substring.py", line 18, in find_substrings
    for chunk in chunks:
RuntimeError: generator raised StopIteration

Расклеивать emoji

Привет, есть предложение считать все символы emoji за отдельные токены.
Сейчас библиотека склеивает их с нормальными словами:
Например, для такого текста:

✅Сдается комната. стиралка,wifi... Сдается без комиссии.Соседи семья без детей.Можно с животными. Вся необходимая инфраструктура в пешей доступности. М. Восстания Ул.Гончарная 8000+счетчики💰 8-906-271-28-93 📲 Все фото на стене🌅

Результат будет следующий:

[Substring(0, 8, '✅Сдается'),
 Substring(9, 16, 'комната'),
 Substring(16, 17, '.'),
 Substring(18, 26, 'стиралка'),
 Substring(26, 27, ','),
 Substring(27, 31, 'wifi'),
 Substring(31, 34, '...'),
 Substring(35, 42, 'Сдается'),
 Substring(43, 46, 'без'),
 Substring(47, 55, 'комиссии'),
 Substring(55, 56, '.'),
 Substring(56, 62, 'Соседи'),
 Substring(63, 68, 'семья'),
 Substring(69, 72, 'без'),
 Substring(73, 78, 'детей'),
 Substring(78, 79, '.'),
 Substring(79, 84, 'Можно'),
 Substring(85, 86, 'с'),
 Substring(87, 96, 'животными'),
 Substring(96, 97, '.'),
 Substring(98, 101, 'Вся'),
 Substring(102, 113, 'необходимая'),
 Substring(114, 128, 'инфраструктура'),
 Substring(129, 130, 'в'),
 Substring(131, 136, 'пешей'),
 Substring(137, 148, 'доступности'),
 Substring(148, 149, '.'),
 Substring(150, 151, 'М'),
 Substring(151, 152, '.'),
 Substring(153, 162, 'Восстания'),
 Substring(163, 165, 'Ул'),
 Substring(165, 166, '.'),
 Substring(166, 175, 'Гончарная'),
 Substring(176, 180, '8000'),
 Substring(180, 181, '+'),
 Substring(181, 190, 'счетчики💰'),
 Substring(191, 206, '8-906-271-28-93'),
 Substring(207, 208, '📲'),
 Substring(209, 212, 'Все'),
 Substring(213, 217, 'фото'),
 Substring(218, 220, 'на'),
 Substring(221, 227, 'стене🌅')]

Ложное разбиение предложений внутри кавычек и скобок, разбиение списков

text = "1. Текст юридической нормы согласно постановлению Правительства РФ от 25.05.2020 №3543 "О размещении информации и т.д. Общие положения" (зарегистрировано Министервом юстиции РФ. Регистрационный номер 3333) выделяются М.М. Мишустиным следующие истории: \n1. История 1; \n2. История 2; \n3.2. История 3\nа) История 2."

На входе есть такой текст (см. выше). По юридическим нормам русского языка это одно предложение

На выходе имеем ложное разбиение предложений внутри скобок, внутри кавычек, и при обработке списков.

Вопросы:

  1. Это сознательное решение о подобном поведении в случаях обработки кавычек и скобок?
  2. Можете подсказать точки изменений, которые позволят подобные вещи исправить и считать текст выше одним предложением?

Заранее спасибо :)

Смайлики из трёх символов не сегментируются в один токен :-)

Тест-кейс:

from razdel import tokenize
print([_.text for _ in tokenize(`:-)`)]) 
# [`:`, `-`, `)`]
  • В регулярке ATOM каждый символ пунктуации рассматривается как отдельный атом, то есть слияние ожидается от процедуры сегментации
  • В процедуре punct судя по всему только содержимое двух атомов приходит, :-, -). Видимо, раньше здесь какое-то другое правило склеивало :- в один буффер, а punct проверяло завершающую скобочку ).
    # SMILE = re.compile(r'^' + r'[=:;]-?[)(]{1,3}' + '$', re.U)
    if SMILE.match(tok.buffer + right):
       return JOIN

Предлагаемый патч, проверяем третий токен

def punct(split):
    if split.left_1.type != PUNCT or split.right_1.type != PUNCT:
        return

    left = split.left
    right = split.right

+    if split.right_2 and SMILE.match(split.buffer + right + split.right_2.text):
+        return JOIN

    if SMILE.match(split.buffer + right):
        return JOIN

    if left in ENDINGS and right in ENDINGS:
        # ... ?!
        return JOIN

    if left + right in ('--', '**'):
        # ***
        return JOIN

Не работает ссылка

Добрый день!
На главной странице анализатора razdel не работает выделенная ссылка (возвращается 404)
image

В DebugSegmenter \n ломают оформление консоли

Встретил проблему при отладке сегментации

На строке DebugSegmenter используются print которые могут сломать вывод отображения

Предлагаю переписать на print(repr(split.left), '|', repr(split.delimiter), '|', repr(split.right))

Таким образом у нас появятся все непечатаемые символы что облегчит разбор отладки

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.