
    /h/                     l    S r SSKrSSKJr  SSKJrJrJrJr  SSK	J
r
   " S S\5      r " S S	\
5      rg)
a  
Lexical translation model that considers word order.

IBM Model 2 improves on Model 1 by accounting for word order.
An alignment probability is introduced, a(i | j,l,m), which predicts
a source word position, given its aligned target word's position.

The EM algorithm used in Model 2 is:

:E step: In the training data, collect counts, weighted by prior
         probabilities.

         - (a) count how many times a source language word is translated
               into a target language word
         - (b) count how many times a particular position in the source
               sentence is aligned to a particular position in the target
               sentence

:M step: Estimate new probabilities based on the counts from the E step

Notations
---------

:i: Position in the source sentence
     Valid values are 0 (for NULL), 1, 2, ..., length of source sentence
:j: Position in the target sentence
     Valid values are 1, 2, ..., length of target sentence
:l: Number of words in the source sentence, excluding NULL
:m: Number of words in the target sentence
:s: A word in the source language
:t: A word in the target language

References
----------

Philipp Koehn. 2010. Statistical Machine Translation.
Cambridge University Press, New York.

Peter E Brown, Stephen A. Della Pietra, Vincent J. Della Pietra, and
Robert L. Mercer. 1993. The Mathematics of Statistical Machine
Translation: Parameter Estimation. Computational Linguistics, 19 (2),
263-311.
    Ndefaultdict)AlignedSent	AlignmentIBMModel	IBMModel1)Countsc                   `   ^  \ rS rSrSrSU 4S jjrS rS rS rS r	S r
S	 rS
 rS rSrU =r$ )	IBMModel2;   u  
Lexical translation model that considers word order

>>> bitext = []
>>> bitext.append(AlignedSent(['klein', 'ist', 'das', 'haus'], ['the', 'house', 'is', 'small']))
>>> bitext.append(AlignedSent(['das', 'haus', 'ist', 'ja', 'groß'], ['the', 'house', 'is', 'big']))
>>> bitext.append(AlignedSent(['das', 'buch', 'ist', 'ja', 'klein'], ['the', 'book', 'is', 'small']))
>>> bitext.append(AlignedSent(['das', 'haus'], ['the', 'house']))
>>> bitext.append(AlignedSent(['das', 'buch'], ['the', 'book']))
>>> bitext.append(AlignedSent(['ein', 'buch'], ['a', 'book']))

>>> ibm2 = IBMModel2(bitext, 5)

>>> print(round(ibm2.translation_table['buch']['book'], 3))
1.0
>>> print(round(ibm2.translation_table['das']['book'], 3))
0.0
>>> print(round(ibm2.translation_table['buch'][None], 3))
0.0
>>> print(round(ibm2.translation_table['ja'][None], 3))
0.0

>>> print(round(ibm2.alignment_table[1][1][2][2], 3))
0.939
>>> print(round(ibm2.alignment_table[1][2][2][2], 3))
0.0
>>> print(round(ibm2.alignment_table[2][2][4][5], 3))
1.0

>>> test_sentence = bitext[2]
>>> test_sentence.words
['das', 'buch', 'ist', 'ja', 'klein']
>>> test_sentence.mots
['the', 'book', 'is', 'small']
>>> test_sentence.alignment
Alignment([(0, 0), (1, 1), (2, 2), (3, 2), (4, 3)])

c                    > [         TU ]  U5        Uc2  [        USU-  5      nUR                  U l        U R	                  U5        OUS   U l        US   U l        [        SU5       H  nU R                  U5        M     U R                  U5        g)a  
Train on ``sentence_aligned_corpus`` and create a lexical
translation model and an alignment model.

Translation direction is from ``AlignedSent.mots`` to
``AlignedSent.words``.

:param sentence_aligned_corpus: Sentence-aligned parallel corpus
:type sentence_aligned_corpus: list(AlignedSent)

:param iterations: Number of iterations to run training algorithm
:type iterations: int

:param probability_tables: Optional. Use this to pass in custom
    probability values. If not specified, probabilities will be
    set to a uniform distribution, or some other sensible value.
    If specified, all the following entries must be present:
    ``translation_table``, ``alignment_table``.
    See ``IBMModel`` for the type and purpose of these tables.
:type probability_tables: dict[str]: object
N   translation_tablealignment_tabler   )	super__init__r   r   set_uniform_probabilitiesr   rangetrain	align_all)selfsentence_aligned_corpus
iterationsprobability_tablesibm1n	__class__s         K/var/www/auris/envauris/lib/python3.13/site-packages/nltk/translate/ibm2.pyr   IBMModel2.__init__c   s    , 	01% 4a*nED%)%;%;D"**+BC &88K%LD"#56G#HD q*%AJJ./ & 	./    c                    [        5       nU H  n[        UR                  5      n[        UR                  5      nXE4U;  d  M6  UR	                  XE45        SUS-   -  nU[
        R                  :  a%  [        R                  " S[        U5      -   S-   5        [        SUS-   5       H0  n[        SUS-   5       H  nX`R                  U   U   U   U'   M     M2     M     g )N   zA source sentence is too long (z& words). Results may be less accurate.r   )setlenmotswordsaddr   MIN_PROBwarningswarnstrr   r   )	r   r   l_m_combinationsaligned_sentencelminitial_probijs	            r   r   #IBMModel2.set_uniform_probabilities   s    5 7$))*A$**+Av-- $$aV, AE{("3"33MM9a&!BC q!a%A"1a!e_;G,,Q/215a8 - ) !8r    c           
         [        5       nU H  nS /UR                  -   nS/UR                  -   n[        UR                  5      n[        UR                  5      nU R	                  XE5      n[        SUS-   5       H_  n	XY   n
[        SUS-   5       HE  nXK   nU R                  XXE5      nXU
   -  nUR                  XU
5        UR                  XXU5        MG     Ma     M     U R                  U5        U R                  U5        g )NUNUSEDr"   r   )Model2Countsr%   r&   r$   prob_all_alignmentsr   prob_alignment_pointupdate_lexical_translationupdate_alignment*maximize_lexical_translation_probabilities maximize_alignment_probabilities)r   parallel_corpuscountsr-   src_sentencetrg_sentencer.   r/   total_countr2   tr1   scountnormalized_counts                  r   r   IBMModel2.train   s    / 6$4$9$99L$:(8(>(>>L$))*A$**+A 22<NK 1a!e_ Oq!a%A$A 55aLWE',1~'=$556F1M++,<qI ) % !0* 	77?--f5r    c                 ~   [         R                  nUR                  R                  5        H  u  p4UR                  5        Hv  u  pVUR                  5        H]  u  pxU HR  n	UR                  U   U   U   U	   UR                  U   U   U	   -  n
[        X5      U R                  U   U   U   U	'   MT     M_     Mx     M     g N)r   r(   	alignmentitemsalignment_for_any_imaxr   )r   r>   r(   r1   j_sr2   src_sentence_lengthsr.   trg_sentence_lengthsr/   estimates              r   r<   *IBMModel2.maximize_alignment_probabilities   s    $$&&,,.FA+.99;'/C/I/I/K+A1",,Q/215a8$88;A>qAB ! <?x;R,,Q/215a8 2 0L ,7 /r    c                     [        [        5      n[        S[        U5      5       H?  nX$   n[        S[        U5      5       H  nX5==   U R	                  XdX5      -  ss'   M!     MA     U$ )a  
Computes the probability of all possible word alignments,
expressed as a marginal distribution over target words t

Each entry in the return value represents the contribution to
the total alignment probability by the target word t.

To obtain probability(alignment | src_sentence, trg_sentence),
simply sum the entries in the return value.

:return: Probability of t for all s in ``src_sentence``
:rtype: dict(str): float
r"   r   )r   floatr   r$   r8   )r   r?   r@   alignment_prob_for_tr2   rB   r1   s          r   r7   IBMModel2.prob_all_alignments   sj      +51q#l+,AA1c,/0$'4+D+D,, ' 1 - $#r    c                     [        U5      S-
  n[        U5      S-
  nX1   nXB   nU R                  U   U   U R                  U   U   U   U   -  $ )zb
Probability that position j in ``trg_sentence`` is aligned to
position i in the ``src_sentence``
r"   )r$   r   r   )	r   r1   r2   r?   r@   r.   r/   rC   rB   s	            r   r8   IBMModel2.prob_alignment_point   se    
 !!OO%%a(+d.B.B1.Ea.H.KA.NNNr    c                 ~   Sn[        UR                  5      S-
  n[        UR                  5      S-
  n[        UR                  5       HY  u  pVUS:X  a  M  UR                  U   nUR                  U   nUU R
                  U   U   U R                  U   U   U   U   -  -  nM[     [        U[        R                  5      $ )zK
Probability of target sentence and an alignment given the
source sentence
g      ?r"   r   )
r$   r?   r@   	enumeraterI   r   r   rL   r   r(   )	r   alignment_infoprobr.   r/   r2   r1   trg_wordsrc_words	            r   prob_t_a_given_sIBMModel2.prob_t_a_given_s   s    
 ++,q0++,q0n667DAAv%2215H%2215H&&x0:&&q)!,Q/23D 8 4**++r    c                 8    U H  nU R                  U5        M     g rH   )align)r   r=   sentence_pairs      r   r   IBMModel2.align_all   s    ,MJJ}% -r    c                 $   / n[        UR                  5      n[        UR                  5      n[        UR                  5       H  u  pVU R                  U   S   U R
                  S   US-      U   U   -  n[        U[        R                  5      nSn[        UR                  5       HA  u  pU R                  U   U
   U R
                  U	S-      US-      U   U   -  nX:  d  M=  UnU	nMC     UR                  XX45        M     [        U5      Ul        g)a  
Determines the best word alignment for one sentence pair from
the corpus that the model was trained on.

The best alignment will be set in ``sentence_pair`` when the
method returns. In contrast with the internal implementation of
IBM models, the word indices in the ``Alignment`` are zero-
indexed, not one-indexed.

:param sentence_pair: A sentence in the source language and its
    counterpart sentence in the target language
:type sentence_pair: AlignedSent
Nr   r"   )r$   r%   r&   rY   r   r   rL   r   r(   appendr   rI   )r   rb   best_alignmentr.   r/   r2   r\   	best_probbest_alignment_pointr1   r]   
align_probs               r   ra   IBMModel2.align  s(    ""###$$]%8%89KA &&x06&&q)!a%03A67  Ix'8'89I#' (););<**84X>**1q51!a%8;A>?  * *I+,(  = !!1";<# :& #,N";r    )r   r   rH   )__name__
__module____qualname____firstlineno____doc__r   r   r   r<   r7   r8   r^   r   ra   __static_attributes____classcell__r   s   @r   r   r   ;   s?    %N'0RH(64
S$.	O,*&&< &<r    r   c                   8   ^  \ rS rSrSrU 4S jrS rS rSrU =r	$ )r6   i*  zc
Data object to store counts of various parameters during training.
Includes counts for alignment.
c                 f   > [         TU ]  5         [        S 5      U l        [        S 5      U l        g )Nc                      [        S 5      $ )Nc                      [        S 5      $ )Nc                       [        [        5      $ rH   r   rS    r    r   <lambda>KModel2Counts.__init__.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>3  s	    K<Nr    r   ry   r    r   rz   9Model2Counts.__init__.<locals>.<lambda>.<locals>.<lambda>3  s
    4N(Or    r   ry   r    r   rz   'Model2Counts.__init__.<locals>.<lambda>3  s
    K OPr    c                      [        S 5      $ )Nc                       [        [        5      $ rH   rx   ry   r    r   rz   r|   6  s	    E(:r    r   ry   r    r   rz   r}   6  s
    K :;r    )r   r   r   rI   rK   )r   r   s    r   r   Model2Counts.__init__0  s/    $P
 $/;$
 r    c                 f    U R                   U   U==   U-  ss'   U R                  U==   U-  ss'   g rH   )	t_given_sany_t_given_s)r   rD   rC   rB   s       r   r9   'Model2Counts.update_lexical_translation9  s1    q!%1&r    c                 ~    U R                   U   U   U   U==   U-  ss'   U R                  U   U   U==   U-  ss'   g rH   rI   rK   )r   rD   r1   r2   r.   r/   s         r   r:   Model2Counts.update_alignment=  sE    q!Q"e+"  #A&q)U2)r    r   )
rk   rl   rm   rn   ro   r   r9   r:   rp   rq   rr   s   @r   r6   r6   *  s    

'3 3r    r6   )ro   r)   collectionsr   nltk.translater   r   r   r   nltk.translate.ibm_modelr	   r   r6   ry   r    r   <module>r      s7   *X  # F F +l< l<^36 3r    