<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta>
      <journal-title-group>
        <journal-title>ORCID:</journal-title>
      </journal-title-group>
    </journal-meta>
    <article-meta>
      <title-group>
        <article-title>A Disambiguator for Pymorphy2 Morphological Analyzer</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Nicolás Cortegoso Vissio</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Victor Zakharov</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>St Petersburg State University</institution>
          ,
          <addr-line>9 Universitetskaya Emb., Saint-Petersburg, 195299</addr-line>
          ,
          <country country="RU">Russia</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2021</year>
      </pub-date>
      <volume>000</volume>
      <fpage>0</fpage>
      <lpage>0003</lpage>
      <abstract>
        <p>Pymorphy2 is a morphological analyzer implemented in Python for Russian. The parser takes a word and, based on its morphology, produces a series of classification hypotheses regarding class, gender, number, case, etc. However, the analysis of the isolated word rarely occurs without any ambiguity. This article presents an implementation of a trigram tag model that works on top of the morphological parsing performed by pymorphy2 and uses the sequence of words in the sentence to choose the most probable morphological interpretation for each word.</p>
      </abstract>
      <kwd-group>
        <kwd>1 Russian language</kwd>
        <kwd>pymorphy2</kwd>
        <kwd>NLP</kwd>
        <kwd>tagger</kwd>
        <kwd>part-of-speech</kwd>
        <kwd>morphological disambiguation</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>Taken separately, Russian word forms often allow for more than one grammatical interpretation.2</p>
      <sec id="sec-1-1">
        <title>Since pymorphy2 parses one word at a time, it returns a list of possible parses with an associated</title>
        <p>probability. When working with bag-of-words models, a common practice is to simply select for each
word form the parse with the highest probability. In this case, assuming only the dictionary form of the
word is required, pymorphy2 will get the correct part-of-speech about 92% of the time. However, if the
grammatical case of the word is taken in consideration, the precision will drop to 82% (see the
experiment’s results in section 6) and the parsing will often produce ungrammatical sequences.</p>
      </sec>
      <sec id="sec-1-2">
        <title>In order to improve the percentages shown in the previous paragraph, the proposal presented in this</title>
        <p>article is to implement a trigram part-of-speech model to disambiguate the morphological analysis that
pymorphy2 performs on the isolated word. The part-of-speech tags of those word classes that have
declensions are augmented with the grammatical case, while other features such as number or gender
are discarded in order to keep the trigram model at a reasonable size and prevent data sparseness when
training it on a rather small corpus.</p>
      </sec>
      <sec id="sec-1-3">
        <title>Since this paper proposes a method to disambiguate pymorphy2 parsing results, it will focus</title>
        <p>exclusively on this morphological analyzer and measure its performance before and after the suggested
extension. It does not intend to be a superior solution to other morphological analyzers available for</p>
      </sec>
      <sec id="sec-1-4">
        <title>Russian, but rather a helper tool for pymorphy2 users. For state-of-the-art taggers or comparisons</title>
        <p>between the performance of pymorphy2 and other available options (mystem3, TreeTagger, FreeLing,
etc.), the reader is referred to the work of Kuzmenko [4] or Kotelnikov et al. [5].</p>
      </sec>
      <sec id="sec-1-5">
        <title>The remainder of the paper will cover: 2. A pymorphy2’s parsing example, 3. Trigram hidden</title>
      </sec>
      <sec id="sec-1-6">
        <title>Markov Model, 4. Training the trigram model, 5. Code implementation example, 6. Testing the model and 7. Conclusions and further work.</title>
      </sec>
    </sec>
    <sec id="sec-2">
      <title>2. A pymorphy2’s parsing example</title>
      <sec id="sec-2-1">
        <title>As noted in the introduction, pymorphy2 processes each word separately and returns one or more "Parse" objects containing the possible parses for the given word form. For example, the morphological analysis of the word forms "мама", "мыла", "раму" produces the following lists (1), (2), (3):</title>
        <p>[</p>
        <p>Parse(word='мама', tag=OpencorporaTag('NOUN,anim,femn sing,nomn'), normal_form='мама', score=1.0,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мама', 1907, 0),))
]
[</p>
        <p>Parse(word='мыла', tag=OpencorporaTag('NOUN,inan,neut sing,gent'), normal_form='мыло', score=0.333333,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мыла', 54, 1),)),</p>
        <p>Parse(word='мыла', tag=OpencorporaTag('VERB,impf,tran femn,sing,past,indc'), normal_form='мыть',
score=0.333333, methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мыла', 1813, 8),)),</p>
        <p>Parse(word='мыла', tag=OpencorporaTag('NOUN,inan,neut plur,nomn'), normal_form='мыло', score=0.166666,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мыла', 54, 6),)),</p>
        <p>Parse(word='мыла', tag=OpencorporaTag('NOUN,inan,neut plur,accs'), normal_form='мыло', score=0.166666,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мыла', 54, 9),))
]
[</p>
        <p>Parse(word='раму', tag=OpencorporaTag('NOUN,inan,masc,Geox sing,datv'), normal_form='рам', score=0.5,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'раму', 32, 2),)),</p>
        <p>
          Parse(word='раму', tag=OpencorporaTag('NOUN,inan,femn sing,accs'), normal_form='рама', score=0.5,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'раму', 55, 3),))
]
(
          <xref ref-type="bibr" rid="ref1">1</xref>
          )
(
          <xref ref-type="bibr" rid="ref2">2</xref>
          )
(
          <xref ref-type="bibr" rid="ref3">3</xref>
          )
        </p>
      </sec>
      <sec id="sec-2-2">
        <title>With the exception of "мама", the other word forms have more than one possible interpretation. In</title>
        <p>
          the case of the noun "раму" the ambiguity arises in gender and case, while "мыла" can be analysed as
2 For example, the nominal and accusative plural cases endings for nouns like "сталь" (declension type 8a according to A. A. Zaliznyak's
classification) are identical for the singular cases of the genitive, dative and locative; most of the singular feminine adjectives in the genitive,
dative, locative and instrumental cases share the same inflection; a word form can even belong to different word classes, like "мыла", that can
be analyzed as a noun or a verb.
a verb or noun. Every parse object inside the list has a parameter "score" with an associated probability.
Korobov [3] states that the score corresponds to the conditional probability p (analysis | word) estimated
on the basis of the OpenCorpora corpus. This is obtained by counting how many times a certain analysis
has been associated with a given word form and, based on these frequencies, its conditional probability
is calculated using Laplace smoothing. The parse objects within the list are sorted according to this
probability in descending order, therefore picking the first item in the list is equivalent to selecting the
parse object with the most probable interpretation for the given word form. For example, the parse
objects with the highest score for each of the word forms analysed in (
          <xref ref-type="bibr" rid="ref1">1</xref>
          ), (
          <xref ref-type="bibr" rid="ref2">2</xref>
          ) and (
          <xref ref-type="bibr" rid="ref3">3</xref>
          ) would be:
        </p>
        <p>Parse(word='мама', tag=OpencorporaTag('NOUN,anim,femn sing,nomn'), normal_form='мама', score=1.0,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мама', 1907, 0),))</p>
        <p>Parse(word='мыла', tag=OpencorporaTag('NOUN,inan,neut sing,gent'), normal_form='мыло', score=0.333333,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мыла', 54, 1),))</p>
        <p>
          Parse(word='раму', tag=OpencorporaTag('NOUN,inan,masc,Geox sing,datv'), normal_form='рам', score=0.5,
methods_stack=((&lt;DictionaryAnalyzer&gt;, 'раму', 32, 2),))
(
          <xref ref-type="bibr" rid="ref4">4</xref>
          )
(
          <xref ref-type="bibr" rid="ref5">5</xref>
          )
(
          <xref ref-type="bibr" rid="ref6">6</xref>
          )
        </p>
        <p>If "мама", "мыла", "раму" are no longer treated as separate tokens, but as words in the sentence
"мама мыла раму", the parse object with the highest score incorrectly classifies the last two. When
working with bag-of-words models and lemmas, the misclassification in case is usually not harmful
(most of the time it will still provide the right dictionary form)3, but a wrong part-of-speech attribution
will produce a different interpretation of the lemma. The next section suggests how the score values can
be combined with the trigram tag model to obtain better results.</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>3. Trigram hidden Markov model</title>
      <sec id="sec-3-1">
        <title>Hidden Markov models (HMM) are probabilistic sequence classifiers that have been widely used in</title>
        <p>NLP tasks like part-of-speech tagging and word class disambiguation. The task of the model is to find
for any string of word forms of the set Ψ (the observable states) the most probable sequence of
part-ofspeech tags of the set Ω (the hidden states). For a better understanding of HMM the reader is referred
to Jurafsky [6] or Bocharov et al. [7]. Although, nowadays POS-taggers are build using more advanced
techniques, for example those based on neural networks, for the purpose envisaged here of eliminating
the ambiguity of the analysis previously carried out by pymorphy2, a modified HMM model would be
an easy solution to implement. The HMM is briefly described below along with the intended
modification to disambiguate the analysis from pymorphy2.</p>
      </sec>
      <sec id="sec-3-2">
        <title>To train an HMM model, it is necessary to calculate two parameters in a tagged corpus: the emission and the transition probabilities.</title>
      </sec>
      <sec id="sec-3-3">
        <title>The emission probabilities</title>
        <p>
          ∨ (
          <xref ref-type="bibr" rid="ref7">7</xref>
          )
where p is the conditional probability that the word wi corresponds to the tag ti. This assumes that
the probability of an output observation wi depends only on the state that produced the observation ti
and not on any other states or observations.
        </p>
      </sec>
      <sec id="sec-3-4">
        <title>The transition probabilities</title>
        <p>
          ∨ , (
          <xref ref-type="bibr" rid="ref8">8</xref>
          )
where p is the probability that the tag ti occurs, provided that is preceded by the tags ti-1 and ti-2. This
assumes that the probability of a particular tag depends only on the previous two tags (trigram).
3 Here the missclassification of “раму” produces a different dictionary form.
        </p>
      </sec>
      <sec id="sec-3-5">
        <title>Trigram HMM</title>
      </sec>
      <sec id="sec-3-6">
        <title>Modified trigram HMM</title>
      </sec>
      <sec id="sec-3-7">
        <title>The HMM tagging algorithm chooses as the most likely tag sequence the one that maximizes the product of two terms: the probability of the sequence of tags (the transition probability) and the probability of each tag generating a word (the emission probability). where p(yi| yi-1, yi–2) is the transition probability and p(xi|yi) is the emission probability.</title>
        <p>
          The approach taken here is to implement the tagging algorithm on top of the pymorphy2 parsing
results and use the score values from the Parse object as the emission probabilities.
∨
∨
,
,
∨
∨
(
          <xref ref-type="bibr" rid="ref9">9</xref>
          )
(10)
where the last term of the equation, the emission probability of a word given a tag, is replaced by
the score value from the pymorphy2 parse: the probability of the analysis given a word.
        </p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>4. Training the trigram POS tag model</title>
      <p>Pymorphy2 not only implements the OpenCorpora dictionary, it also adopts the same set of tags. To
take advantage of this fact, the model was trained on the OpenCorpora labeled subcorpus with
homonyms removed [8] (26011 sentences, 256311 tokens, 188319 words), so no modifications on the
tags were required. As mentioned in the previous section, the emission probabilities are directly
replaced by the score values from the parse objects. Therefore, only the transition probabilities in the
corpus were calculated on the basis of the following 49 tags, which were obtained by combining the 20
basic part-of-speech tags from pymorphy2/OpenCorpora and the grammatical case (where applicable):</p>
      <p>As table 2 shows, those part-of-speech that have declensions, were augmented with the grammatical
case. Gender and number were not taken into account to keep the tag set within reasonable limits. It
was assumed that case is a good predictor to be included in the transition probabilities (although this
hypothesis remains to be proven). Table 4 presents a fragment of the resulting matrix with the transition
probabilities. The cells contain the conditional probability for the tag in the row when it is preceded by
the two tags from the columns. For example, the probability that an adjective in the nominative case
appears at the very beginning of the sentence is 0.0731339900. Those combinations that were not
observed in the corpus were assigned a very small probability of 0.000000001; for instance an adjective
in any other case than is not instrumental after an adjective in the instrumental case at the beginning of
the sentence. The transition probabilities were stored in a JSON-format file.</p>
    </sec>
    <sec id="sec-5">
      <title>5. Code implementation example</title>
      <p>The code written in python6 implements the Viterbi algorithm to find the most probable sequence of
parse objects from the morphological analysis performed by pymorphy2. It takes as input the JSON file
with the transition probabilities and a list that contains all the possible parse objects that pymorphy2
returns for each word. The output is a new list with only one parse object per word. The code and the
file with the transition probabilities are available for download from a GitHub repository [9].
4 Symbol for “start of sentence”.
5 Symbol for “end of sentence”.
6 System requirements: python3, pymorphy2 version 0.8.</p>
      <p>Code implementation example
from pymorphy2 import MorphAnalyzer #1
from hmmtrigram import MostProbableTagSequence #2
morph = MorphAnalyzer() #3
token_list = ['Мама', 'мыла', 'Раму', '.'] #4
pymorphy2_parsed = [morph.parse(token) for token in token_list] #5
mpts = MostProbableTagSequence('transition_probabilities.json') #6
mpts.get_sequence(pymorphy2_parsed) #7
#1: imports the class for morphological analysis from the package “pymorphy2”
#2: imports the class for calculating the most probable tag sequence from “hmmtrigram”
#3: instantiates the object “morph” from the class “MorphAnalyzer”
#4: any list of tokens
#5: the “parse” method of the “morph” object parses each token in the list and stores the parsing
results in the new list “pymorphy2_parsed”</p>
      <p>#6: instantiates the object “mpts” from the class “MostProbableTagSequence” with the name of the
json file that contains the transition probabilities as argument</p>
      <p>#7: the “get_sequence” method of the “mpts” object takes the list with the parse objects stored in
“pymorphy2_parsed” and returns a new list with the most probable parsing for the sequence of tokens.</p>
      <sec id="sec-5-1">
        <title>Code output</title>
        <p>[
Parse(word='мама', tag=OpencorporaTag('NOUN,anim,femn sing,nomn'),
normal_form='мама', score=1.0, methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мама', 1907,
0),)),
Parse(word='мыла', tag=OpencorporaTag('VERB,impf,tran femn,sing,past,indc'),
normal_form='мыть', score=0.333333, methods_stack=((&lt;DictionaryAnalyzer&gt;, 'мыла',
1813, 8),)),
Parse(word='раму', tag=OpencorporaTag('NOUN,inan,femn sing,accs'),
normal_form='рама', score=0.5, methods_stack=((&lt;DictionaryAnalyzer&gt;, 'раму', 55,
3),)),
Parse(word='.', tag=OpencorporaTag('PNCT'), normal_form='.', score=1.0,
methods_stack=((&lt;PunctuationAnalyzer&gt;, '.'),))
]
(11)
(12)</p>
      </sec>
      <sec id="sec-5-2">
        <title>The most probable sequence correctly disambiguates 'мама' as a noun in the nominative case, 'мыла' as verb and 'раму' as a noun in the accusative case.</title>
      </sec>
    </sec>
    <sec id="sec-6">
      <title>6. Testing the model</title>
      <sec id="sec-6-1">
        <title>The test was conducted on the OpenCorpora subcorpus without homonyms and unknown words of 10966 sentences, 72671 tokens and 50433 words. The experiment presents the results for 55 275 tokens (no punctuation marks).</title>
      </sec>
      <sec id="sec-6-2">
        <title>The baseline summarizes the results of selecting the parse object with the highest score for each independent word form (the first item in the list that pymorphy2 generates).</title>
        <p>Table 5 shows the averaged precision and recall for the 20 part-of-speech tags (the base POS tags
without case). This outlines the performance that can be expected of getting the right part-of-speech
(POS) tag for a given word form. When grammatical case is also taken into account (augmented tags),
these values drop significantly (compare with the baseline in table 6).</p>
      </sec>
      <sec id="sec-6-3">
        <title>Conjunctions and interjections constitute the two cases within the 49 tags where the implementation of the trigram model performs slightly below the baseline.</title>
      </sec>
    </sec>
    <sec id="sec-7">
      <title>7. Conclusions and further work</title>
      <p>The testing results support the benefit of applying the trigram model to disambiguate the analysis
preformed by pymorphy2. However, if pymorphy2 is being used only to get the part-of-speech or the
dictionary form of the words within a bag-of-words model, the suggested extension will produce little
improvement over the baseline. For that purpose, selecting the first parse object in the list will be
enough. The implementation of the trigram model to choose the most probable sequence of parse objects
is useful for those tasks that require valid POS tag sequences or greater precision in determining the
grammatical case of a word. In Russian, by disambiguating the grammatical case of a word form, most
of the time its gender and number are also obtained correctly. The effects of broadening the combination
of part of speech + case with respect to number and / or gender remain to be explored.</p>
    </sec>
    <sec id="sec-8">
      <title>8. References</title>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <surname>Documentation</surname>
          </string-name>
          .
          <article-title>Morphological analyzer pymorphy2</article-title>
          . URL: https://pymorphy2.readthedocs.io/en/stable/user/index.html
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          <article-title>[2] OpenCorpora</article-title>
          . URL: http://opencorpora.org/
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>M.</given-names>
            <surname>Korobov</surname>
          </string-name>
          , Morphological Analyzer and
          <article-title>Generator for Russian and Ukranian Languages</article-title>
          ,
          <source>in: Analysis of Images, Social Networks and Texts</source>
          ,
          <year>2015</year>
          , pp.
          <fpage>320</fpage>
          -
          <lpage>332</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>Е.</given-names>
            <surname>Kuzmenko</surname>
          </string-name>
          ,
          <article-title>Morphological Analysis for Russian: Integration and Comparison of Taggers</article-title>
          , in: D.
          <string-name>
            <surname>Ignatov</surname>
          </string-name>
          et al. (
          <article-title>eds) Analysis of Images, Social Networks and Texts</article-title>
          .
          <source>AIST 2016. Communications in Computer and Information Science</source>
          , vol.
          <volume>661</volume>
          , Springer, Cham,
          <year>2017</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>E.</given-names>
            <surname>Kotelnikov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>E.</given-names>
            <surname>Razova</surname>
          </string-name>
          and
          <string-name>
            <given-names>I.</given-names>
            <surname>Fishcheva</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A Close</given-names>
            <surname>Look at Russian Morphological</surname>
          </string-name>
          <article-title>Parsers: Which One Is the Best? in: Communications in Computer</article-title>
          and Information Science,
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>D.</given-names>
            <surname>Jurafsky</surname>
          </string-name>
          and
          <string-name>
            <given-names>J.</given-names>
            <surname>Martin</surname>
          </string-name>
          ,
          <article-title>Speech and language processing: An introduction to natural language processing, computional linguistics, and speech recognition, 2nd</article-title>
          . ed. Pearson, Upper Saddle River, New Jersey,
          <year>2009</year>
          , pp.
          <fpage>139</fpage>
          -
          <lpage>151</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>V.</given-names>
            <surname>Bocharov</surname>
          </string-name>
          and
          <string-name>
            <given-names>O.</given-names>
            <surname>Mitrenina</surname>
          </string-name>
          , Computer morphology, in: I.
          <string-name>
            <surname>Nikolaev</surname>
            ,
            <given-names>O.</given-names>
          </string-name>
          <string-name>
            <surname>Mitrenina</surname>
            and T. Lando (eds), 2nd. ed.,
            <given-names>URSS</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Saint</surname>
            <given-names>Petersburg</given-names>
          </string-name>
          ,
          <year>2017</year>
          , pp.
          <fpage>14</fpage>
          -
          <lpage>33</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <surname>Downloads</surname>
          </string-name>
          . OpenCorpus. URL: http://opencorpora.org/?page=downloads
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>N.</given-names>
            <surname>Cortegoso-Vissio</surname>
          </string-name>
          .
          <article-title>Github repository</article-title>
          . URL: https://github.com/nicolascortegoso/morphological_analyzer_for_russian
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>