Ë
    çÍ:j  ã                   óL   — d Z 	 ddlZdd„Zd„ Zd„ Zd	d„Zd
d„Zy# e$ r Y Œw xY w)a  
Text Segmentation Metrics

1. Windowdiff

Pevzner, L., and Hearst, M., A Critique and Improvement of
  an Evaluation Metric for Text Segmentation,
  Computational Linguistics 28, 19-36


2. Generalized Hamming Distance

Bookstein A., Kulyukin V.A., Raita T.
Generalized Hamming Distance
Information Retrieval 5, 2002, pp 353-375

Baseline implementation in C++
http://digital.cs.usu.edu/~vkulyukin/vkweb/software/ghd/ghd.html

Study describing benefits of Generalized Hamming Distance Versus
WindowDiff for evaluating text segmentation tasks
Begsten, Y.  Quel indice pour mesurer l'efficacite en segmentation de textes ?
TALN 2009


3. Pk text segmentation metric

Beeferman D., Berger A., Lafferty J. (1999)
Statistical Models for Text Segmentation
Machine Learning, 34, 177-210
é    Nc                 ó€  — t        | «      t        |«      k7  rt        d«      ‚|t        | «      kD  rt        d«      ‚d}t        t        | «      |z
  dz   «      D ]Q  }t        | |||z    j	                  |«      ||||z    j	                  |«      z
  «      }|r||z  }ŒC|t        d|«      z  }ŒS |t        | «      |z
  dz   z  S )a  
    Compute the windowdiff score for a pair of segmentations.  A
    segmentation is any sequence over a vocabulary of two items
    (e.g. "0", "1"), where the specified boundary value is used to
    mark the edge of a segmentation.

    From Pevzner & Hearst (2002), the WindowDiff metric is defined as::

        WindowDiff(ref, hyp, k) =
            1 / (N - k) * sum_{i=1}^{N-k} (
                |b(ref, i, i+k) - b(hyp, i, i+k)| > 0
            )

    where ``b(seg, i, j)`` counts the number of boundaries in ``seg``
    between positions ``i`` and ``j``, and ``N = len(seg)``.

    The weighted variant sums the absolute differences instead
    of thresholding at 1.

        >>> s1 = "000100000010"
        >>> s2 = "000010000100"
        >>> s3 = "100000010000"
        >>> '%.2f' % windowdiff(s1, s1, 3)
        '0.00'
        >>> '%.2f' % windowdiff(s1, s2, 3)
        '0.30'
        >>> '%.2f' % windowdiff(s2, s3, 3)
        '0.80'

    :param seg1: a segmentation
    :type seg1: str or list
    :param seg2: a segmentation
    :type seg2: str or list
    :param k: window width
    :type k: int
    :param boundary: boundary value
    :type boundary: str or int or bool
    :param weighted: use the weighted variant of windowdiff
    :type weighted: boolean
    :rtype: float
    z!Segmentations have unequal lengthzCWindow width k should be smaller or equal than segmentation lengthsr   é   ç      ð?)ÚlenÚ
ValueErrorÚrangeÚabsÚcountÚmin)Úseg1Úseg2ÚkÚboundaryÚweightedÚwdÚiÚndiffs           ún/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/nltk/metrics/segmentation.pyÚ
windowdiffr   1   sÓ   € ôV ˆ4ƒy”C˜“IÒÜÐ<Ó=Ð=ØŒ3ˆt‹9‚}ÜØQó
ð 	
ð 
€BÜ”3�t“9˜q‘= 1Ñ$Ó%ò  ˆÜ�D˜˜Q ™U�O×)Ñ)¨(Ó3°d¸1¸qÀ1¹u°o×6KÑ6KÈHÓ6UÑUÓVˆÙØ�%‰K‰Bà”#�a˜“-Ñ‰Bð ð ”�T“˜Q‘ Ñ$Ñ%Ð%ó    c                 ó°   — t        j                  | |f«      }|t        j                  |«      z  |dd d …f<   |t        j                  | «      z  |d d …df<   |S )Nr   )ÚnpÚemptyÚarange)ÚnrowsÚncolsÚins_costÚdel_costÚmats        r   Ú	_init_matr    o   sO   € Ü
�(‰(�E˜5�>Ó
"€CØœ2Ÿ9™9 UÓ+Ñ+€CˆŠ1ˆ�IØœ2Ÿ9™9 UÓ+Ñ+€CŠˆ1ˆ�IØ€Jr   c                 ó
  — t        |«      D ]u  \  }}t        |«      D ]b  \  }}	|t        ||	z
  «      z  | ||f   z   }
||	k(  r| ||f   }n ||	kD  r|| ||dz   f   z   }n|| |dz   |f   z   }t        ||
«      | |dz   |dz   f<   Œd Œw y )Nr   )Ú	enumerater	   r   )r   ÚrowvÚcolvr   r   Úshift_cost_coeffr   ÚrowiÚjÚcoljÚ
shift_costÚtcosts               r   Ú_ghd_auxr+   v   s¶   € Ü˜T“?ò 7‰ˆˆ4Ü  “ò 	7‰GˆAˆtØ)¬C°°t±Ó,<Ñ<¸sÀ1ÀaÀ4¹yÑHˆJØ�tŠ|à˜A˜q˜D™	‘Ø˜’à  3 q¨!¨a©% x¡=Ñ0‘ð ! 3 q¨1¡u¨a x¡=Ñ0�Ü # E¨:Ó 6ˆC��A‘�q˜1‘u�Òñ	7ñ7r   c                 óˆ  — t        | «      D ��cg c]  \  }}||k(  sŒ|‘Œ }}}t        |«      D ��cg c]  \  }}||k(  sŒ|‘Œ }	}}t        |«      }
t        |	«      }|
dk(  r|dk(  ry|
dkD  r
|dk(  r|
|z  S |
dk(  r
|dkD  r||z  S t        |dz   |
dz   ||«      }t        ||	||||«       t	        |d   «      S c c}}w c c}}w )av  
    Compute the Generalized Hamming Distance for a reference and a hypothetical
    segmentation, corresponding to the cost related to the transformation
    of the hypothetical segmentation into the reference segmentation
    through boundary insertion, deletion and shift operations.

    A segmentation is any sequence over a vocabulary of two items
    (e.g. "0", "1"), where the specified boundary value is used to
    mark the edge of a segmentation.

    Recommended parameter values are a shift_cost_coeff of 2.
    Associated with a ins_cost, and del_cost equal to the mean segment
    length in the reference segmentation.

        >>> # Same examples as Kulyukin C++ implementation
        >>> ghd('1100100000', '1100010000', 1.0, 1.0, 0.5)
        0.5
        >>> ghd('1100100000', '1100000001', 1.0, 1.0, 0.5)
        2.0
        >>> ghd('011', '110', 1.0, 1.0, 0.5)
        1.0
        >>> ghd('1', '0', 1.0, 1.0, 0.5)
        1.0
        >>> ghd('111', '000', 1.0, 1.0, 0.5)
        3.0
        >>> ghd('000', '111', 1.0, 2.0, 0.5)
        6.0

    :param ref: the reference segmentation
    :type ref: str or list
    :param hyp: the hypothetical segmentation
    :type hyp: str or list
    :param ins_cost: insertion cost
    :type ins_cost: float
    :param del_cost: deletion cost
    :type del_cost: float
    :param shift_cost_coeff: constant used to compute the cost of a shift.
        ``shift cost = shift_cost_coeff * |i - j|`` where ``i`` and ``j``
        are the positions indicating the shift
    :type shift_cost_coeff: float
    :param boundary: boundary value
    :type boundary: str or int or bool
    :rtype: float
    r   g        r   )éÿÿÿÿr-   )r"   r   r    r+   Úfloat)ÚrefÚhypr   r   r%   r   r   ÚvalÚref_idxÚhyp_idxÚ
nref_boundÚ
nhyp_boundr   s                r   Úghdr6   †   sÜ   € ô\ "+¨3£×C‘X�a˜°3¸(³?ŠqÐC€GÑCÜ!*¨3£×C‘X�a˜°3¸(³?ŠqÐC€GÑCä�W“€JÜ�W“€Jà�Q‚˜:¨š?ØØ	�aŠ˜J¨!šOØ˜HÑ$Ð$Ø	�qŠ˜Z¨!š^Ø˜HÑ$Ð$ä
�J ‘N J°¡N°H¸hÓ
G€CÜˆS�'˜7 H¨hÐ8HÔIÜ��V‘ÓÐùó DùÛCs   �B8�B8²B>Á B>c                 óR  — |€2t        t        t        | «      | j                  |«      dz  z  «      «      }d}t	        t        | «      |z
  dz   «      D ]A  }| |||z    j                  |«      dkD  }||||z    j                  |«      dkD  }||k7  sŒ=|dz  }ŒC |t        | «      |z
  dz   z  S )aù  
    Compute the Pk metric for a pair of segmentations A segmentation
    is any sequence over a vocabulary of two items (e.g. "0", "1"),
    where the specified boundary value is used to mark the edge of a
    segmentation.

    >>> '%.2f' % pk('0100'*100, '1'*400, 2)
    '0.50'
    >>> '%.2f' % pk('0100'*100, '0'*400, 2)
    '0.50'
    >>> '%.2f' % pk('0100'*100, '0100'*100, 2)
    '0.00'

    :param ref: the reference segmentation
    :type ref: str or list
    :param hyp: the segmentation to evaluate
    :type hyp: str or list
    :param k: window size, if None, set to half of the average reference segment length
    :type boundary: str or int or bool
    :param boundary: boundary value
    :type boundary: str or int or bool
    :rtype: float
    ç       @r   r   r   )ÚintÚroundr   r
   r   )r/   r0   r   r   Úerrr   ÚrÚhs           r   Úpkr>   É   s½   € ð2 	€yÜ””c˜#“h #§)¡)¨HÓ"5¸Ñ";Ñ<Ó=Ó>ˆà
€CÜ”3�s“8˜a‘< !Ñ#Ó$ò ˆØ��A˜‘EˆN× Ñ  Ó*¨QÑ.ˆØ��A˜‘EˆN× Ñ  Ó*¨QÑ.ˆØ�‹6Ø�1‰H‰Cð	ð
 ”#�c“(˜Q‘, Ñ$Ñ%Ð%r   )Ú1F)r8   r8   r   r?   )Nr?   )	Ú__doc__Únumpyr   ÚImportErrorr   r    r+   r6   r>   © r   r   ú<module>rD      sC   ðñð@	Ûó
8&ò|ò7ó =ôF"&øðy ò 	Ùð	ús   „ ›#¢#