
    QdJ7                         d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
 ddlmZ  G d de	          Z G d	 d
e          ZdS )a  
Translation model that considers how a word can be aligned to
multiple words in another language.

IBM Model 3 improves on Model 2 by directly modeling the phenomenon
where a word in one language may be translated into zero or more words
in another. This is expressed by the fertility probability,
n(phi | source word).

If a source word translates into more than one word, it is possible to
generate sentences that have the same alignment in multiple ways. This
is modeled by a distortion step. The distortion probability, d(j|i,l,m),
predicts a target word position, given its aligned source word's
position. The distortion probability replaces the alignment probability
of Model 2.

The fertility probability is not applicable for NULL. Target words that
align to NULL are assumed to be distributed uniformly in the target
sentence. The existence of these words is modeled by p1, the probability
that a target word produced by a real source word requires another
target word that is produced by NULL.

The EM algorithm used in Model 3 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 target
               sentence is aligned to a particular position in the source
               sentence
         - (c) count how many times a source word is aligned to phi number
               of target words
         - (d) count how many times NULL is aligned to a target word

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

Because there are too many possible alignments, only the most probable
ones are considered. First, the best alignment is determined using prior
probabilities. Then, a hill climbing approach is used to find other good
candidates.

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
:phi: Fertility, the number of target words produced by a source word
:p1: Probability that a target word produced by a source word is
     accompanied by another target word that is aligned to NULL
:p0: 1 - p1

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)	factorial)AlignedSent	AlignmentIBMModel	IBMModel2)Countsc                   F     e Zd ZdZd	 fd	Z fdZd Zd Zd Zd Z	 xZ
S )
	IBMModel3u$  
    Translation model that considers how a word can be aligned to
    multiple words in another language

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

    >>> ibm3 = IBMModel3(bitext, 5)

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

    >>> print(round(ibm3.distortion_table[1][1][2][2], 3))
    1.0
    >>> print(round(ibm3.distortion_table[1][2][2][2], 3))
    0.0
    >>> print(round(ibm3.distortion_table[2][2][4][5], 3))
    0.75

    >>> print(round(ibm3.fertility_table[2]['summarize'], 3))
    1.0
    >>> print(round(ibm3.fertility_table[1]['book'], 3))
    1.0

    >>> print(round(ibm3.p1, 3))
    0.054

    >>> 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, None), (4, 3)])

    Nc                    t                                          |           |                                  |>t          ||          }|j        | _        |j        | _        |                     |           nA|d         | _        |d         | _        |d         | _        |d         | _        |d         | _	        t          d|          D ]}|                     |           dS )a  
        Train on ``sentence_aligned_corpus`` and create a lexical
        translation model, a distortion model, a fertility model, and a
        model for generating NULL-aligned words.

        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``,
            ``fertility_table``, ``p1``, ``distortion_table``.
            See ``IBMModel`` for the type and purpose of these tables.
        :type probability_tables: dict[str]: object
        Ntranslation_tablealignment_tablefertility_tablep1distortion_tabler   )super__init__reset_probabilitiesr	   r   r   set_uniform_probabilitiesr   r   r   rangetrain)selfsentence_aligned_corpus
iterationsprobability_tablesibm2n	__class__s         3lib/python3.11/site-packages/nltk/translate/ibm3.pyr   zIBMModel3.__init__   s    0 	0111  """%4jAAD%)%;D"#'#7D **+BCCCC &88K%LD"#56G#HD #56G#HD (.DG$67I$JD!q*%% 	0 	0AJJ.////	0 	0    c                 x     t                                                       t           fd           _        d S )Nc                  (    t           fd          S )Nc                  (    t           fd          S )Nc                  (    t           fd          S )Nc                       j         S N)MIN_PROBr   s   r    <lambda>zeIBMModel3.reset_probabilities.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>   s	     r!   r   r)   s   r    r*   zSIBMModel3.reset_probabilities.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>   s    K8M8M8M8M,N,N r!   r   r)   s   r    r*   zAIBMModel3.reset_probabilities.<locals>.<lambda>.<locals>.<lambda>   s    $N$N$N$NOO r!   r   r)   s   r    r*   z/IBMModel3.reset_probabilities.<locals>.<lambda>   s    KOOOO  r!   )r   r   r   r   r   r   s   `r    r   zIBMModel3.reset_probabilities   sJ    ##%%% +   !
 !

	 	r!   c                    t                      }|D ]}t          |j                  }t          |j                  }||f|vr|                    ||f           d|z  }|t
          j        k     r't          j        dt          |          z   dz              t          d|dz             D ]4}t          d|dz             D ]}|| j        |         |         |         |<   5t          d           | j        d<   t          d           | j        d<   t          d           | j        d<   t          d	           | j        d
<   d}	d|	dz
  z  t          d|	          D ]}
t          fd          | j        |
<   d| _        d S )N   zA target sentence is too long (z& words). Results may be less accurate.r   c                      dS )Ng? r/   r!   r    r*   z5IBMModel3.set_uniform_probabilities.<locals>.<lambda>       c r!   c                      dS )Ng?r/   r/   r!   r    r*   z5IBMModel3.set_uniform_probabilities.<locals>.<lambda>       d r!   c                      dS )Ng?r/   r/   r!   r    r*   z5IBMModel3.set_uniform_probabilities.<locals>.<lambda>   r0   r!      c                      dS )Ng{Gz?r/   r/   r!   r    r*   z5IBMModel3.set_uniform_probabilities.<locals>.<lambda>   r2   r!      
   g{Gz?   c                       S r'   r/   )initial_fert_probs   r    r*   z5IBMModel3.set_uniform_probabilities.<locals>.<lambda>   s    <M r!   g      ?)setlenmotswordsaddr   r(   warningswarnstrr   r   r   r   r   )r   r   l_m_combinationsaligned_sentencelminitial_probjiMAX_FERTILITYphir:   s              @r    r   z#IBMModel3.set_uniform_probabilities   s   55 7 	I 	I$)**A$*++A1v--- $$aV,,, 1u("333M9a&&!BC  
 q!a% I IA"1a!e__ I I<H-a03A6q99I #.kk":":Q"-ll";";Q"-kk":":Q"-ll";";Q MA$56M** 	O 	OC(34M4M4M4M(N(ND %%r!   c           
      4   t                      }|D ]}t          |j                  }t          |j                  }|                     |          \  }}t          |                                          |_        |                     |          }|D ]}	| 	                    |	          }
|
|z  }t          d|dz             D ]2}|                    ||	|           |                    ||	|||           3|                    ||	           |                    ||	           | j        }|                                  || _        |                     |           |                     |           |                     |           |                     |           d S )Nr-   )Model3Countsr<   r=   r>   sampler   zero_indexed_alignment	alignmentprob_of_alignmentsprob_t_a_given_sr   update_lexical_translationupdate_distortionupdate_null_generationupdate_fertilityr   r   *maximize_lexical_translation_probabilities!maximize_distortion_probabilities maximize_fertility_probabilities&maximize_null_generation_probabilities)r   parallel_corpuscountsrD   rE   rF   sampled_alignmentsbest_alignmenttotal_countalignment_infocountnormalized_countrH   existing_alignment_tables                 r    r   zIBMModel3.train   s    / 	J 	J$)**A$*++A 26=M1N1N.)25577* *&
 112DEEK #5 J J--n==#(;#6 q!a% X XA55(.!   ,,-=~qRSUVWWWW--.>OOO''(8.IIIIJ $(#7   """777???..v666--f55533F;;;;;r!   c                    t           j        }|j                                        D ]\  }}|                                D ]\  }}|                                D ]m\  }}|D ]e}	|j        |         |         |         |	         |j        |         |         |	         z  }
t          |
|          | j        |         |         |         |	<   fnd S r'   )r   r(   
distortionitemsdistortion_for_any_jmaxr   )r   r\   r(   rH   i_srI   src_sentence_lengthsrE   trg_sentence_lengthsrF   estimates              r    rX   z+IBMModel3.maximize_distortion_probabilities	  s   $'--// 	T 	TFAs+.99;; T T''/C/I/I/K/K T T+A+1 T T"-a03A6q9$9!<Q?BC ! =@(<S<S-a03A6q99TTT	T 	Tr!   c                 6   |j         }|j        }t          |          dz
  }t          |          dz
  }| j        }d|z
  }d}t          j        }	|                    d          }
|t          ||
          t          ||d|
z  z
            z  z  }||	k     r|	S t          d|
dz             D ]}|||
z
  |z
  dz   |z  z  }||	k     r|	c S t          d|dz             D ]M}|                    |          }|t          |          | j
        |         ||                  z  z  }||	k     r|	c S Nt          d|dz             D ]_}||         }|j        |         }||         }|| j        |         |         | j        |         |         |         |         z  z  }||	k     r|	c S `|S )zc
        Probability of target sentence and an alignment given the
        source sentence
        r-   g      ?r   r4   )src_sentencetrg_sentencer<   r   r   r(   fertility_of_ipowr   r   r   rP   r   r   )r   r`   rn   ro   rE   rF   r   p0probabilityr(   null_fertilityrI   	fertilityrH   tss                   r    rR   zIBMModel3.prob_t_a_given_s  s
   
 &2%2!!WV$ (66q99s2~..RQ=O9O1P1PPP!!O q.1,-- 	  	 AA.2Q6!;;KX%% & q!a% 	  	 A&55a88I)$$t';I'F|TU'WWK X%% & q!a% 		  		 AQA(+AQA&q)!,t/DQ/G/J1/Ma/PPK X%% & r!   r'   )__name__
__module____qualname____doc__r   r   r   r   rX   rR   __classcell__r   s   @r    r   r   W   s        / /b*0 *0 *0 *0 *0 *0X
 
 
 
 
  >'< '< '<R
T 
T 
T0 0 0 0 0 0 0r!   r   c                   (     e Zd ZdZ fdZd Z xZS )rM   zp
    Data object to store counts of various parameters during training.
    Includes counts for distortion.
    c                     t                                                       t          d           | _        t          d           | _        d S )Nc                  "    t          d           S )Nc                  "    t          d           S )Nc                  "    t          d           S )Nc                      dS Ng        r/   r/   r!   r    r*   z]Model3Counts.__init__.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>Q  s    PS r!   r   r/   r!   r    r*   zKModel3Counts.__init__.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>Q  s    K<T<T r!   r   r/   r!   r    r*   z9Model3Counts.__init__.<locals>.<lambda>.<locals>.<lambda>Q  s    4T4T(U(U r!   r   r/   r!   r    r*   z'Model3Counts.__init__.<locals>.<lambda>Q  s    K U UVV r!   c                  "    t          d           S )Nc                  "    t          d           S )Nc                      dS r   r/   r/   r!   r    r*   zKModel3Counts.__init__.<locals>.<lambda>.<locals>.<lambda>.<locals>.<lambda>T  s    C r!   r   r/   r!   r    r*   z9Model3Counts.__init__.<locals>.<lambda>.<locals>.<lambda>T  s    KK(@(@ r!   r   r/   r!   r    r*   z'Model3Counts.__init__.<locals>.<lambda>T  s    K @ @AA r!   )r   r   r   re   rg   r+   s    r    r   zModel3Counts.__init__N  sP    %VV
 
 %0AA%
 %
!!!r!   c                     |j         |         }| j        |         |         |         |xx         |z  cc<   | j        |         |         |xx         |z  cc<   d S r'   )rP   re   rg   )r   ra   r`   rH   rE   rF   rI   s          r    rT   zModel3Counts.update_distortionW  sk    $Q'1a ###u,###!!$Q'***e3*****r!   )rx   ry   rz   r{   r   rT   r|   r}   s   @r    rM   rM   H  sQ         

 
 
 
 
4 4 4 4 4 4 4r!   rM   )r{   r@   collectionsr   mathr   nltk.translater   r   r   r	   nltk.translate.ibm_modelr
   r   rM   r/   r!   r    <module>r      s   E EN  # # # # # #       F F F F F F F F F F F F + + + + + +n n n n n n n nb4 4 4 4 46 4 4 4 4 4r!   