model_diagnosis / service /src /matcher.py
Volodimirich's picture
Upload folder using huggingface_hub
5cd3fef verified
Raw
History Blame Contribute Delete
2.04 kB
import typing as t
import pymorphy3
import re
import ujson as json
import pathlib
from transliterate import translit
from functools import lru_cache
from .config import Keys, Paths
from collections import defaultdict
CACHE_SIZE = 256
class Matcher:
def __init__(self):
self.morph = pymorphy3.MorphAnalyzer(lang="ru")
self.pairs: dict[str, tuple[float, bool]] = json.loads(pathlib.Path(Paths.PAIRS).read_text())
self.preprocess: dict[str, str] = json.loads(pathlib.Path(Paths.PREPROCESSOR).read_text())
def __call__(self, key: Keys) -> t.Callable:
match key:
case Keys.DIAG:
return self.match_diags
case Keys.DOC:
return self.match_doctors
raise KeyError
def match_doctors(self, doc: str, other_doc: str) -> bool:
if not doc or not other_doc:
return False
words: set[str] = self.text_to_words(doc)
other_words: set[str] = self.text_to_words(other_doc)
return len(words & other_words) / min(len(words), len(other_words), 1) > 0.49
def match_diags(self, raw_diag: str, raw_other_diag: str) -> bool:
diag: str = self.preprocess.get(raw_diag, "")
other_diag: str = self.preprocess.get(raw_other_diag, "")
if not diag or not other_diag:
return False
if diag == other_diag:
return True
pair_check: bool | None = self.pairs.get(f"{diag}|{other_diag}", None)
if pair_check is not None:
return pair_check[1]
reverse_pair_check: bool | None = self.pairs.get(f"{other_diag}|{diag}", None)
if reverse_pair_check is not None:
return reverse_pair_check[1]
return True
@lru_cache(maxsize=CACHE_SIZE)
def text_to_words(self, input_text: str) -> set[str]:
text = input_text.lower()
text = translit(text, "ru")
text = re.sub(r"[^а-я_]+", " ", text).strip()
return set([self.morph.parse(word)[0].normal_form for word in text.split()])