Advertisement
Guest User

Untitled

a guest
Aug 7th, 2021
12
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.27 KB | None | 0 0
  1. import collections
  2. import itertools
  3. from typing import Iterable, Iterator, Mapping, Tuple
  4.  
  5.  
  6. _EMPTY_DICT = {}
  7.  
  8.  
  9. class _Epsilon(str):
  10.     def __str__(self):
  11.         return '<END>'
  12.  
  13.  
  14. # Конец строки
  15. EPS = _Epsilon()
  16.  
  17.  
  18. def _pairs(string: str) -> Iterator[Tuple[str, str]]:
  19.     return zip(string, itertools.chain(itertools.islice(string, 1, len(string)),
  20.                                        (EPS,)))
  21.  
  22.  
  23. class ConfidenceModel:
  24.     def __init__(self, usernames: Iterable[str]):
  25.         self._model = self._prepare(usernames)
  26.    
  27.     def __str__(self) -> str:
  28.         return '\n'.join(
  29.             f'{prev_c} -> ({"; ".join(f"{next_c} -> {prob:.4f}" for next_c, prob in probs.items())})'
  30.             for prev_c, probs in self._model.items()
  31.         )
  32.    
  33.     @staticmethod
  34.     def _prepare(usernames: Iterable[str]) -> Mapping[str, Mapping[str, float]]:
  35.         """
  36.        Подсчёт уверенности следования символов: result[x][y] равно
  37.        "увереннясти" модели в том, что после символа x следует символ y.
  38.        "Увереннясть" в данном случае подсчитывается как отношение абсолютной вероятности
  39.        пары x->y к максимальной вероятности для символа x.
  40.        Няпример, если после x идут символы y, z, w с вероятностями 1/2, 1/3, 1/6 соответствення,
  41.        то уверенность для них будет равна 1 (1/2 : 1/2), 2/3 (1/3 : 1/2) и 1/3 (1/6 : 1/2) соответствення.
  42.        """
  43.         model = collections.defaultdict(lambda: collections.defaultdict(lambda: 0.0))
  44.         for name in usernames:
  45.             for prev_c, next_c in _pairs(name):
  46.                 model[prev_c][next_c] += 1
  47.        
  48.         max_numbers: Dict[str, int] = {
  49.             prev_c: max(numbers.values())
  50.             for prev_c, numbers in model.items()
  51.         }
  52.        
  53.         return {
  54.             prev_c: {
  55.                 next_c: next_c_number / max_numbers[prev_c]
  56.                 for next_c, next_c_number in numbers.items()
  57.             }
  58.             for prev_c, numbers in model.items()
  59.         }
  60.    
  61.     def pair_cofidence(self, prev_c: str, next_c: str) -> float:
  62.         """
  63.        Уверенность в том, что после символа prev_c следует символ
  64.        next_c. Плавающая няшка от 1.0 до 0.0.
  65.        """
  66.         return self._model.get(prev_c, _EMPTY_DICT).get(next_c, 0.0)
  67.  
  68.     def word_confidence(self, word: str) -> float:
  69.         """
  70.        Уверенность в том, что word — "правильный" ник.
  71.        Плавающая няшка от 1.0 до 0.0.
  72.        """
  73.         confidence = 1.0
  74.        
  75.         word_len = len(word)
  76.         for prev_c, next_c in _pairs(word):
  77.             char_confidence = self.pair_cofidence(prev_c, next_c)
  78.             #print(f'{prev_c} -> {next_c} = {char_confidence}')
  79.             confidence -= (1 - char_confidence) / word_len
  80.        
  81.         return confidence
  82.    
  83.     def __getitem__(self, word: str) -> float:
  84.         return self.word_confidence(word)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement