
    wfh!                        d dl mZ d dlZd dlZd dlmZ d dlmZmZm	Z	 d dl
Z
d dlmZ d dlmZ erd dlZd dlmZ d dlmZ  ej*                  e      Z G d	 d
e      Zy)    )annotationsN)defaultdict)TYPE_CHECKINGAnyLiteral)TripletEvaluator)append_to_last_row)SimilarityFunction)SparseEncoderc                       e Zd ZdZ	 	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d	 fdZ fdZ	 d
	 	 	 	 	 	 	 	 	 d fdZ	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 	 	 ddZd fdZ	 xZ
S )SparseTripletEvaluatora  
    This evaluator extends :class:`~sentence_transformers.evaluation.TripletEvaluator` but is specifically designed for sparse encoder models.

    Evaluate a model based on a triplet: (sentence, positive_example, negative_example).
    Checks if ``similarity(sentence, positive_example) < similarity(sentence, negative_example) + margin``.

    Args:
        anchors (List[str]): Sentences to check similarity to. (e.g. a query)
        positives (List[str]): List of positive sentences
        negatives (List[str]): List of negative sentences
        main_similarity_function (Union[str, SimilarityFunction], optional):
            The similarity function to use. If not specified, use cosine similarity,
            dot product, Euclidean, and Manhattan similarity. Defaults to None.
        margin (Union[float, Dict[str, float]], optional): Margins for various similarity metrics.
            If a float is provided, it will be used as the margin for all similarity metrics.
            If a dictionary is provided, the keys should be 'cosine', 'dot', 'manhattan', and 'euclidean'.
            The value specifies the minimum margin by which the negative sample should be further from
            the anchor than the positive sample. Defaults to None.
        name (str): Name for the output. Defaults to "".
        batch_size (int): Batch size used to compute embeddings. Defaults to 16.
        show_progress_bar (bool): If true, prints a progress bar. Defaults to False.
        write_csv (bool): Write results to a CSV file. Defaults to True.
        max_active_dims (Optional[int], optional): The maximum number of active dimensions to use.
            `None` uses the model's current `max_active_dims`. Defaults to None.
        similarity_fn_names (List[str], optional): List of similarity function names to evaluate.
            If not specified, evaluate using the ``model.similarity_fn_name``.
            Defaults to None.

    Example:
        ::

            import logging

            from datasets import load_dataset

            from sentence_transformers import SparseEncoder
            from sentence_transformers.sparse_encoder.evaluation import SparseTripletEvaluator

            logging.basicConfig(format="%(message)s", level=logging.INFO)

            # Load a model
            model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

            # Load triplets from the AllNLI dataset
            # The dataset contains triplets of (anchor, positive, negative) sentences
            dataset = load_dataset("sentence-transformers/all-nli", "triplet", split="dev[:1000]")

            # Initialize the SparseTripletEvaluator
            evaluator = SparseTripletEvaluator(
                anchors=dataset[:1000]["anchor"],
                positives=dataset[:1000]["positive"],
                negatives=dataset[:1000]["negative"],
                name="all_nli_dev",
                batch_size=32,
                show_progress_bar=True,
            )

            # Run the evaluation
            results = evaluator(model)
            '''
            TripletEvaluator: Evaluating the model on the all_nli_dev dataset:
            Accuracy Dot Similarity:        85.40%
            Model Anchor Sparsity: Active Dimensions: 103.0, Sparsity Ratio: 0.9966
            Model Positive Sparsity: Active Dimensions: 67.4, Sparsity Ratio: 0.9978
            Model Negative Sparsity: Active Dimensions: 65.9, Sparsity Ratio: 0.9978
            '''
            # Print the results
            print(f"Primary metric: {evaluator.primary_metric}")
            # => Primary metric: all_nli_dev_dot_accuracy
            print(f"Primary metric value: {results[evaluator.primary_metric]:.4f}")
            # => Primary metric value: 0.8540

    c                n    |
| _         t        t              | _        t        |   |||||||||	||      S )N)anchors	positives	negativesmain_similarity_functionmarginname
batch_sizeshow_progress_bar	write_csvsimilarity_fn_namesmain_distance_function)max_active_dimsr   listsparsity_statssuper__init__)selfr   r   r   r   r   r   r   r   r   r   r   r   	__class__s                /home/chris/cleankitchens-env/lib/python3.12/site-packages/sentence_transformers/sparse_encoder/evaluation/SparseTripletEvaluator.pyr   zSparseTripletEvaluator.__init__b   sR      /)$/w%=!/ 3#9   
 	
    c                x    t         |   |       dD ]%  }| j                  j                  | d| dg       ' y )Nanchorpositivenegative_active_dims_sparsity_ratio)r   _append_csv_headerscsv_headersextend)r   r   prefixr    s      r!   r*   z*SparseTripletEvaluator._append_csv_headers   sI    #$788 	[F##x|%<>X$YZ	[r"   c                r   t        t              | _        t        |   ||||      }| j                  j                         D ])  \  }}t        |      t        |      z  | j                  |<   + |j                  | j                  | j                  | j                               | j                  ||||       t        j                  d| j                  d   dd| j                  d   d       t        j                  d| j                  d	   dd| j                  d
   d       t        j                  d| j                  d   dd| j                  d   d       |X| j                  rLt        t         j"                  j%                  || j&                        | j                  j)                                |S )N)modeloutput_pathepochstepsz*Model Anchor Sparsity: Active Dimensions: anchor_active_dimsz.1fz, Sparsity Ratio: anchor_sparsity_ratioz.4fz,Model Positive Sparsity: Active Dimensions: positive_active_dimspositive_sparsity_ratioz,Model Negative Sparsity: Active Dimensions: negative_active_dimsnegative_sparsity_ratio)r   r   r   r   __call__itemssumlenupdateprefix_name_to_metricsr    store_metrics_in_model_card_dataloggerinfor   r	   ospathjoincsv_filevalues)	r   r/   r0   r1   r2   metricskeyvaluer    s	           r!   r9   zSparseTripletEvaluator.__call__   s    *$/'"Ku\a"b--335 	?JC'*5zCJ'>D$	? 	t2243F3F		RS--eWeUK89L9LMa9bcf8ggyz~  {N  {N  Of  {g  hk  zl  m	
 	:4;N;NOe;fgj:kk}  C  R  R  Sl  m  nq  ~r  s	
 	:4;N;NOe;fgj:kk}  C  R  R  Sl  m  nq  ~r  s	
 "t~~[$--8##**,
 r"   c           	     F    |j                   |f| j                  | j                  dd| j                  d|}|j	                  |      }g dt        | j                        dz     }|j                         D ](  \  }}| j                  | d|    j                  |       * |S )NT)r   r   convert_to_sparse_tensorsave_to_cpur   r$      _)	encoder   r   r   sparsityr<   r   r:   append)	r   r/   	sentenceskwargs
embeddingsstatr-   rH   rI   s	            r!   embed_inputsz#SparseTripletEvaluator.embed_inputs   s     "U\\
"44%) 00
 

 ~~j)3C8K8K4LPQ4QR**, 	AJC6(!C5 1299%@	Ar"   c                B    |j                   j                  | |||       y )N)r1   step)model_card_dataset_evaluation_metrics)r   r/   rG   r1   rX   s        r!   r?   z7SparseTripletEvaluator.store_metrics_in_model_card_data   s"     	44T7%VZ4[r"   c                Z    t         |          }| j                  | j                  |d<   |S )Nr   )r   get_config_dictr   )r   config_dictr    s     r!   r\   z&SparseTripletEvaluator.get_config_dict   s3    g-/+-1-A-AK)*r"   )	NN    FTNN
deprecated)r   	list[str]r   ra   r   ra   r   str | SimilarityFunction | Noner   zfloat | dict[str, float] | Noner   strr   intr   boolr   re   r   z
int | Noner   z?list[Literal['cosine', 'dot', 'euclidean', 'manhattan']] | Noner   rb   )Nrf   )
r/   r   r0   z
str | Noner1   rd   r2   rd   returnzdict[str, float])r/   r   rR   zstr | list[str] | np.ndarrayrg   ztorch.Tensor)r   r   )
r/   r   rG   dict[str, Any]r1   rd   rX   rd   rg   None)rg   rh   )__name__
__module____qualname____doc__r   r*   r9   rV   r?   r\   __classcell__)r    s   @r!   r   r      sF   H^ EI26"'&*_cBN

 
 	

 #B
 0
 
 
  
 
 $
 ]
 !@
>[ ce"1;KN\_	6 0
 
, Z[\"\-;\DG\SV\	\
 r"   r   )
__future__r   loggingrB   collectionsr   typingr   r   r   torch sentence_transformers.evaluationr   sentence_transformers.utilr	   numpynp*sentence_transformers.similarity_functionsr
   2sentence_transformers.sparse_encoder.SparseEncoderr   	getLoggerrj   r@   r    r"   r!   <module>r|      sO    "  	 # . .  = 9MP 
		8	$h- hr"   