§
    íóÉj$  ã                   óP   — d Z 	 ddlZn# e$ r Y nw xY wdd„Zd„ Zd„ Zdd
„Zdd„ZdS )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
é    NÚ1Fc                 óº  — t          | ¦  «        t          |¦  «        k    rt          d¦  «        ‚|dk     rt          d¦  «        ‚|t          | ¦  «        k    rt          d¦  «        ‚d}| d|…                              |¦  «        }|d|…                              |¦  «        }t          t          | ¦  «        |z
  dz   ¦  «        D ]}|dk    rJ|| ||z   dz
           |k    | |dz
           |k    z
  z  }||||z   dz
           |k    ||dz
           |k    z
  z  }t	          ||z
  ¦  «        }	|r||	z  }Œl|t          d|	¦  «        z  }Œ€|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
    ú!Segmentations have unequal lengthr   ú%Window width k should not be negativezCWindow width k should be smaller or equal than segmentation lengthsNé   ç      ð?)ÚlenÚ
ValueErrorÚcountÚrangeÚabsÚmin)
Úseg1Úseg2ÚkÚboundaryÚweightedÚwdÚcount1Úcount2ÚiÚndiffs
             ú|/home/lighthouse/badge-speaker-benchmark/.benchmark-venv-community/lib/python3.11/site-packages/nltk/metrics/segmentation.pyÚ
windowdiffr   1   s  € õV ˆ4�y„y•C˜‘I”IÒÐÝÐ<Ñ=Ô=Ð=Øˆ1‚u€uÝÐ@ÑAÔAÐAØ�3ˆt‰9Œ9‚}€}ÝØQñ
ô 
ð 	
ð 
€Bð
 �"�1�"ŒX�^Š^˜HÑ%Ô%€FØ�"�1�"ŒX�^Š^˜HÑ%Ô%€FÝ•3�t‘9”9˜q‘= 1Ñ$Ñ%Ô%ð 
 ð 
 ˆØˆqŠ5ˆ5ð �t˜A ™E A™I”¨(Ò2°t¸AÀ¹E´{ÀhÒ7NÑOÑOˆFØ�t˜A ™E A™I”¨(Ò2°t¸AÀ¹E´{ÀhÒ7NÑOÑOˆFÝ�F˜V‘OÑ$Ô$ˆØð 	 Ø�%‰KˆBˆBà•#�a˜‘-”-ÑˆBˆ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%   |   sZ   € Ý
Œ(�E˜5�>Ñ
"Ô
"€CØ�2œ9 UÑ+Ô+Ñ+€Cˆˆ1ˆ1ˆ1ˆ�IØ�2œ9 UÑ+Ô+Ñ+€Cˆˆˆˆ1ˆ�IØ€Jr   c                 ó@  — t          |¦  «        D ]�\  }}t          |¦  «        D ]x\  }}	|t          ||	z
  ¦  «        z  | ||f         z   }
||	k    r| ||f         }n'||	k    r|| ||dz   f         z   }n|| |dz   |f         z   }t          ||
¦  «        | |dz   |dz   f<   ŒyŒŽd S )Nr   )Ú	enumerater   r   )r$   ÚrowvÚcolvr"   r#   Úshift_cost_coeffr   ÚrowiÚjÚcoljÚ
shift_costÚtcosts               r   Ú_ghd_auxr0   ƒ   sÚ   € Ý˜T‘?”?ð 7ð 7‰ˆˆ4Ý  ‘”ð 	7ð 	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Ô 6ˆC��A‘�q˜1‘u�ÑÐð	7ð7ð 7r   ç       @r   c                 óŽ  ‡— ˆfd„t          | ¦  «        D ¦   «         }ˆfd„t          |¦  «        D ¦   «         }t          |¦  «        }t          |¦  «        }	|dk    r|	dk    rdS |dk    r|	dk    r||z  S |dk    r|	dk    r|	|z  S t          |	dz   |dz   ||¦  «        }
t          |
|||||¦  «         t	          |
d         ¦  «        S )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
    c                 ó&   •— g | ]\  }}|‰k    ¯|‘ŒS © r4   ©Ú.0r   Úvalr   s      €r   ú
<listcomp>zghd.<locals>.<listcomp>Á   ó"   ø€ ÐCÐCÐC‘X�a˜°3¸(²?°?ˆq°?°?°?r   c                 ó&   •— g | ]\  }}|‰k    ¯|‘ŒS r4   r4   r5   s      €r   r8   zghd.<locals>.<listcomp>Â   r9   r   r   g        r   )éÿÿÿÿr;   )r'   r	   r%   r0   Úfloat)ÚrefÚhypr"   r#   r*   r   Úref_idxÚhyp_idxÚ
nref_boundÚ
nhyp_boundr$   s        `     r   ÚghdrC   “   sï   ø€ ð\ DÐCÐCÐC¥¨3¡¤ÐCÑCÔC€GØCÐCÐCÐC¥¨3¡¤ÐCÑCÔC€Gå�W‘”€JÝ�W‘”€Jà�Q‚€˜:¨š?˜?ØˆsØ	�aŠˆ˜J¨!šO˜OØ˜HÑ$Ð$Ø	�qŠˆ˜Z¨!š^˜^Ø˜HÑ$Ð$å
�J ‘N J°¡N°H¸hÑ
GÔ
G€CÝˆS�'˜7 H¨hÐ8HÑIÔIÐIÝ��V”ÑÔÐr   c           
      óî  — t          | ¦  «        t          |¦  «        k    rt          d¦  «        ‚|€Pt          t          t          | ¦  «        t	          |                      |¦  «        d¦  «        dz  z  ¦  «        ¦  «        }|dk     rt          d¦  «        ‚d}| d|…                              |¦  «        }|d|…                              |¦  «        }t          t          | ¦  «        |z
  dz   ¦  «        D ]i}|dk    rJ|| ||z   dz
           |k    | |dz
           |k    z
  z  }||||z   dz
           |k    ||dz
           |k    z
  z  }|dk    }|dk    }	||	k    r|dz  }Œj|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   Nr   r1   r   r   r   )r	   r
   ÚintÚroundÚmaxr   r   )
r=   r>   r   r   ÚerrÚ	ref_countÚ	hyp_countr   ÚrÚhs
             r   ÚpkrM   Ö   s‡  € õ2 ˆ3�x„x•3�s‘8”8ÒÐÝÐ<Ñ=Ô=Ð=Ø€yõ
 ••c˜#‘h”h¥# c§i¢i°Ñ&9Ô&9¸1Ñ"=Ô"=ÀÑ"CÑDÑEÔEÑFÔFˆØˆ1‚u€uÝÐ@ÑAÔAÐAà
€Cð
 �B�Q�B”—’˜hÑ'Ô'€IØ�B�Q�B”—’˜hÑ'Ô'€IÝ•3�s‘8”8˜a‘< !Ñ#Ñ$Ô$ð 	ð 	ˆØˆqŠ5ˆ5ð ˜#˜a !™e a™iœ.¨HÒ4¸¸QÀ¹U¼ÀxÒ9OÑPÑPˆIØ˜#˜a !™e a™iœ.¨HÒ4¸¸QÀ¹U¼ÀxÒ9OÑPÑPˆIØ˜ŠMˆØ˜ŠMˆØ�Š6ˆ6Ø�1‰HˆCøØ•#�c‘(”(˜Q‘, Ñ$Ñ%Ð%r   )r   F)r1   r1   r   r   )Nr   )	Ú__doc__Únumpyr   ÚImportErrorr   r%   r0   rC   rM   r4   r   r   ú<module>rQ      s®   ððð ð@	ØÐÐÐÐøØð 	ð 	ð 	Ø€Dð	øøøðE&ð E&ð E&ð E&ðVð ð ð7ð 7ð 7ð =ð =ð =ð =ðF5&ð 5&ð 5&ð 5&ð 5&ð 5&s   „	 ‰�