
    Qd2%                     Z    d Z ddlZddlmZ ddlmZmZmZ ddlm	Z	  G d de          Z
dS )ab  
Lexical translation model that ignores word order.

In IBM Model 1, word order is ignored for simplicity. As long as the
word alignments are equivalent, it doesn't matter where the word occurs
in the source or target sentence. Thus, the following three alignments
are equally likely::

    Source: je mange du jambon
    Target: i eat some ham
    Alignment: (0,0) (1,1) (2,2) (3,3)

    Source: je mange du jambon
    Target: some ham eat i
    Alignment: (0,2) (1,3) (2,1) (3,1)

    Source: du jambon je mange
    Target: eat i some ham
    Alignment: (0,3) (1,2) (2,0) (3,1)

Note that an alignment is represented here as
(word_index_in_target, word_index_in_source).

The EM algorithm used in Model 1 is:

:E step: In the training data, count how many times a source language
         word is translated into a target language word, weighted by
         the prior probability of the translation.

:M step: Estimate the new probability of translation based on the
         counts from the Expectation 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
: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)Countsc                   N     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	d	 Z
d
 Z xZS )	IBMModel1u  
    Lexical translation model that ignores 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']))

    >>> ibm1 = IBMModel1(bitext, 5)

    >>> print(round(ibm1.translation_table['buch']['book'], 3))
    0.889
    >>> print(round(ibm1.translation_table['das']['book'], 3))
    0.062
    >>> print(round(ibm1.translation_table['buch'][None], 3))
    0.113
    >>> print(round(ibm1.translation_table['ja'][None], 3))
    0.073

    >>> 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)])

    Nc                    t                                          |           ||                     |           n|d         | _        t	          d|          D ]}|                     |           |                     |           dS )ae  
        Train on ``sentence_aligned_corpus`` and create a lexical
        translation 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, the following entry must be present:
            ``translation_table``.
            See ``IBMModel`` for the type and purpose of this table.
        :type probability_tables: dict[str]: object
        Ntranslation_tabler   )super__init__set_uniform_probabilitiesr   rangetrain	align_all)selfsentence_aligned_corpus
iterationsprobability_tablesn	__class__s        3lib/python3.11/site-packages/nltk/translate/ibm1.pyr   zIBMModel1.__init__l   s    , 	0111%**+BCCCC &88K%LD"q*%% 	0 	0AJJ.////./////    c                    dt          | j                  z  t          j        k     r9t	          j        dt          t          | j                            z   dz              | j        D ]}t          fd          | j        |<   d S )N   z)Target language vocabulary is too large (z& words). Results may be less accurate.c                       S N )initial_probs   r   <lambda>z5IBMModel1.set_uniform_probabilities.<locals>.<lambda>   s    L r   )	len	trg_vocabr   MIN_PROBwarningswarnstrr   r   )r   r   tr   s      @r   r   z#IBMModel1.set_uniform_probabilities   s    3t~...(+++M;c$.))**+00    	J 	JA(34H4H4H4H(I(ID"1%%	J 	Jr   c                 \   t                      }|D ]}|j        }d g|j        z   }|                     ||          }|D ]X}|D ]S}|                     ||          }	|	||         z  }
|j        |         |xx         |
z  cc<   |j        |xx         |
z  cc<   TY|                     |           d S r   )r   wordsmotsprob_all_alignmentsprob_alignment_point	t_given_sany_t_given_s*maximize_lexical_translation_probabilities)r   parallel_corpuscountsaligned_sentencetrg_sentencesrc_sentencetotal_countr'   scountnormalized_counts              r   r   zIBMModel1.train   s    / 	@ 	@+1L 6$4$99L 22<NNK " @ @% @ @A 55a;;E',{1~'=$$Q'***.>>***(+++/??++++	@@ 	77?????r   c           	          t          d           }|D ]+}|D ]&}||xx         |                     ||          z  cc<   ',|S )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
        c                      dS )Ng        r   r   r   r   r    z/IBMModel1.prob_all_alignments.<locals>.<lambda>   s    3 r   )r   r,   )r   r4   r3   alignment_prob_for_tr'   r6   s         r   r+   zIBMModel1.prob_all_alignments   sq      +;;77 	K 	KA! K K$Q'''4+D+DQ+J+JJ''''K##r   c                 (    | j         |         |         S )z|
        Probability that word ``t`` in the target sentence is aligned to
        word ``s`` in the source sentence
        )r   )r   r6   r'   s      r   r,   zIBMModel1.prob_alignment_point   s    
 %a(++r   c                     d}t          |j                  D ]<\  }}|dk    r|j        |         }|j        |         }|| j        |         |         z  }=t          |t          j                  S )zc
        Probability of target sentence and an alignment given the
        source sentence
        g      ?r   )	enumerate	alignmentr3   r4   r   maxr   r#   )r   alignment_infoprobjitrg_wordsrc_words          r   prob_t_a_given_szIBMModel1.prob_t_a_given_s   sy    
 n677 	? 	?DAqAvv%215H%215HD*84X>>DD4*+++r   c                 :    |D ]}|                      |           d S r   )align)r   r0   sentence_pairs      r   r   zIBMModel1.align_all   s0    , 	& 	&MJJ}%%%%	& 	&r   c                 \   g }t          |j                  D ]\  }}t          | j        |         d         t          j                  }d}t          |j                  D ]"\  }}| j        |         |         }	|	|k    r|	}|}#|                    ||f           t          |          |_	        dS )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
        N)
r>   r)   r@   r   r   r#   r*   appendr   r?   )
r   rJ   best_alignmentrC   rE   	best_probbest_alignment_pointrD   rF   
align_probs
             r   rI   zIBMModel1.align   s     $]%899 
	= 
	=KAxD28<TBHDUVVI#' ();<< - -8!3H=hG
** *I+,(!!1&:";<<<<"+N";";r   r   )__name__
__module____qualname____doc__r   r   r   r+   r,   rG   r   rI   __classcell__)r   s   @r   r	   r	   K   s         @!0 !0 !0 !0 !0 !0FJ J J@ @ @($ $ $(, , ,, , , & & &< < < < < < <r   r	   )rT   r$   collectionsr   nltk.translater   r   r   nltk.translate.ibm_modelr   r	   r   r   r   <module>rY      s   4 4l  # # # # # # ; ; ; ; ; ; ; ; ; ; + + + + + +p< p< p< p< p< p< p< p< p< p<r   