ruwordnet 0.0.6
A Python wrapper for the RuWordNet thesaurus.
License: MIT

# python-ruwordnet
This is a Python wrapper for the [RuWordNet](https://ruwordnet.ru/en) thesaurus.

Это питонячья обёртка для тезауруса [RuWordNet](https://ruwordnet.ru/ru).

В настоящий момент поддержана версия 2021 года (RuWordNet 2.0): 59905 синсетов 
(смысловых групп), 154111 значений слов и словосочетаний. 

Аналогичные и связанные проекты: 
- https://www.nltk.org/howto/wordnet.html (оригинальный английский Wordnet)
- https://github.com/jamsic/ru-wordnet (русский тезаурус, выкачанный из wiktionary)
- https://nlpub.ru/Russian_Distributional_Thesaurus#Гиперонимы (русский тезаурус, собранный автоматическими эвристиками в большом корпусе)

## Что это такое
RuWordNet --- это один из немногих тезаурусов для русского языка.

Тезаурус --- это машиночитаемый словарь какого-то языка, 
составленный лингвистами и содержащий информацию о связях между словами.

RuWordNet разбит на *синсеты* --- наборы синонимичных слов и словосочетаний.
Между синсетами установлены бинарные отношения, такие, как *гипоним-гипероним*, 
то есть "частное-общее". Например, "спаржа" является частным случаем "овощей".
Такая разметка на синонимы и гиперонимы позволяет устанавливать отношения
между словами с большей надёжностью (по крайней мере, в теории), 
чем при помощи word2vec и прочей дистрибутивной семантики.

Основными сущностями в тезаурусе являются `Sense` (смысл) - одно конкретное
слово или словосочетание с конкретным же значением, а также `Synset` (синсет) - 
множество сущностей `Sense` с одинаковыми значениями и с одной частью речи. 
Части речи поддержано три: существительное `N`, глагол `V`, и прилагательное `A`.
Некоторые `Sense` состоят из нескольких слов, и часть речи им присваивается
по главному слову.

В текущей версии тезауруса поддержаны следующие отношения между синсетами:
- `hyponyms` / `hypernyms` : более частные и более общие понятия, например,
"спаржа" / "овощи"
- `domains` / `domain_items`: домены и их атрибуты, например, "спорт" / "мяч"
- `meronyms` / `holonyms`: части и целые, например, "желудь" / "дуб"
- `classes` / `instances` : классы и экземпляры, например, "Смоленск" / "областной центр"
- `premises` / `conclusions`: предпосылки и возможные выводы из них, например, 
  "прибежать" / "бегать" (поддержано только для глаголов)
- `causes` / `effects`: причины и следствия, например, "толпиться" / "переснимать" (только для глаголов)
- `pos_synonyms`: синонимы из других частей речи
- `antonyms`: антонимы
- `related`: прочие смысловые связи, например, "овощи" / "овощехранилище"
- `ili`: interlingual index, то есть аналогичный синсет в другом языке (английском)

Кроме того, есть отношения между смыслами:
- `words` / `phrases` - из каких слов состоит фраза, и в каких фразах участвует
слово, например, "чувство" / "порыв чувств"
- `sources` / `derivations` - от каких слов произошло данное, и какие произошли
от него, например, "приятель" / "приятельский"
  
В данном пакете тезаурус обёрнут в ORM `SQLAlchemy`. Это значит, что вы можете
скачать его содержимое в виде текстовой базы sqlite, либо переложить его в
свою собственную базу данных.


## Как запускать
Чтобы воспользоваться тезаурусом, выберите одну из двух опций:
1. Либо клонируйте этот репозиторий;
2. Либо установите пакет и скачайте файл с тезаурусом (около 80 мб):
```commandline
pip install ruwordnet
ruwordnet download
```

В настоящий момент существует несколько версий тезауруса:
* версия 2020 года содержится в файле `ruwordnet/static/ruwordnet.db`, 
    и доступна в версии пакета `ruwordnet>=0.0.2`.
* версия 2021 года (RuWordNet 2.0) содержится в файле `ruwordnet/static/ruwordnet-2021.db`, 
    и доступна по умолчанию начиная с версии пакета `ruwordnet>=0.0.4`.
    В этой версии увеличился размер словаря и добавились свойства 
    `related` (произвольная связь с другим синсетом) 
    и `ili` (interlingual index, т.е. связь с английским WordNet) у синсетов.

Для применения пакета нужно создать объект `RuWordNet`:
```python
from ruwordnet import RuWordNet
wn = RuWordNet()
```

Если вы не использовали команду `ruwordnet download`, вы можете самостоятельно
указать путь до файла либо передать в конструктор открытую сессию SQLAlchemy:
```python
from ruwordnet import RuWordNet
wn = RuWordNet(filename_or_session='ruwordnet/static/ruwordnet-2021.db')
```

После этого можно, например, искать синсеты, в которые входит слово
```python
for sense in wn.get_senses('замок'):
    print(sense.synset)
# Synset(id="126228-N", title="СРЕДНЕВЕКОВЫЙ ЗАМОК")
# Synset(id="114707-N", title="ЗАМОК ДЛЯ ЗАПИРАНИЯ")
```

Для каждого синсета можно глядеть на гиперонимы...
```python
wn.get_senses('спаржа')[0].synset.hypernyms
# [Synset(id="348-N", title="ОВОЩИ"),
#  Synset(id="4789-N", title="ТРАВЯНИСТОЕ РАСТЕНИЕ"),
#  Synset(id="6878-N", title="ОВОЩНАЯ КУЛЬТУРА")]
```
... или, наоборот, на гипонимы
```python
vegetables = wn.get_senses('спаржа')[0].synset.hypernyms[0]
vegetables.hyponyms
# [Synset(id="107993-N", title="АРТИШОК"),
# Synset(id="108482-N", title="СПАРЖА"),
# Synset(id="118660-N", title="ЗЕЛЕНЫЙ ГОРОШЕК"),
# ...
```

## Поиск в тезаурусе
Обращаясь к объекту `RuWordNet` с помощью квадратных скобок, можно извлекать русские и английские 
синсеты (по id) и смыслу (по id или тексту). 
```Python
wn['134045-N']
# Synset(id="134045-N", title="ПОТЕНЦИАЛ (ФИЗИЧЕСКАЯ ВЕЛИЧИНА)")
wn['11493827-n']
# WNSynset(id="11493827-n", definition="the difference in electrical charge between two points in a circuit expressed in volts")
wn['134045-N-189287']
# Sense(id="134045-N-189287", name="ПОТЕНЦИАЛ")
wn['electric_potential%1:19:00::']
# WNSense(key="electric_potential%1:19:00::", name="electric_potential")
wn['потенциал']
# [Sense(id="134045-N-189287", name="ПОТЕНЦИАЛ"), Sense(id="134046-N-189287", name="ПОТЕНЦИАЛ")]
wn['potential']
# [WNSense(key="potential%1:19:00::", name="potential"), WNSense(key="potential%3:00:00::", name="potential"), WNSense(key="potential%1:26:00::", name="potential")]
```

Кроме этого, есть специальные методы для поиска русских или английских синсетов и значений.
```Python
wn.get_synset_by_id("134045-N")
wn.get_en_synset_by_id("11493827-n")
wn.get_senses('потенциал')
wn.get_synsets('потенциал')
wn.get_en_senses('potential')
wn.get_en_synsets('potential')
```

**Предупреждение**: для английского WordNet представлены не все элементы, а только связанные с RuWordNet.

Больше примеров использования есть в .ipynb файлах в данном репозитории.