
    wfhS#                        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
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)BinaryClassificationEvaluator)append_to_last_row)Tensor)SparseEncoderc                       e Zd ZdZ	 	 	 	 	 	 d		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d
 fdZd fdZ	 d	 	 	 	 	 	 	 	 	 d fdZd fdZ	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 	 	 ddZ	d fdZ
 xZS )#SparseBinaryClassificationEvaluatora  
    This evaluator extends :class:`~sentence_transformers.evaluation.BinaryClassificationEvaluator` but is specifically designed for sparse encoder models.

    Evaluate a model based on the similarity of the embeddings by calculating the accuracy of identifying similar and
    dissimilar sentences.
    The metrics are the cosine similarity, dot score, Euclidean and Manhattan distance
    The returned score is the accuracy with a specified metric.

    The results are written in a CSV. If a CSV already exists, then values are appended.

    The labels need to be 0 for dissimilar pairs and 1 for similar pairs.

    Args:
        sentences1 (List[str]): The first column of sentences.
        sentences2 (List[str]): The second column of sentences.
        labels (List[int]): labels[i] is the label for the pair (sentences1[i], sentences2[i]). Must be 0 or 1.
        name (str, optional): Name for the output. Defaults to "".
        batch_size (int, optional): Batch size used to compute embeddings. Defaults to 32.
        show_progress_bar (bool, optional): If true, prints a progress bar. Defaults to False.
        write_csv (bool, optional): 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 (Optional[List[Literal["cosine", "dot", "euclidean", "manhattan"]]], optional): The similarity functions to use. If not specified, defaults to the ``similarity_fn_name`` attribute of the model. Defaults to None.

    Example:
        ::

            import logging

            from datasets import load_dataset

            from sentence_transformers import SparseEncoder
            from sentence_transformers.sparse_encoder.evaluation import SparseBinaryClassificationEvaluator

            logging.basicConfig(format="%(asctime)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.INFO)

            # Initialize the SPLADE model
            model = SparseEncoder("naver/splade-cocondenser-ensembledistil")

            # Load a dataset with two text columns and a class label column (https://huggingface.co/datasets/sentence-transformers/quora-duplicates)
            eval_dataset = load_dataset("sentence-transformers/quora-duplicates", "pair-class", split="train[-1000:]")

            # Initialize the evaluator
            binary_acc_evaluator = SparseBinaryClassificationEvaluator(
                sentences1=eval_dataset["sentence1"],
                sentences2=eval_dataset["sentence2"],
                labels=eval_dataset["label"],
                name="quora_duplicates_dev",
                show_progress_bar=True,
                similarity_fn_names=["cosine", "dot", "euclidean", "manhattan"],
            )
            results = binary_acc_evaluator(model)
            '''
            Accuracy with Cosine-Similarity:             75.00      (Threshold: 0.8668)
            F1 with Cosine-Similarity:                   67.22      (Threshold: 0.5974)
            Precision with Cosine-Similarity:            54.18
            Recall with Cosine-Similarity:               88.51
            Average Precision with Cosine-Similarity:    67.81
            Matthews Correlation with Cosine-Similarity: 49.56

            Accuracy with Dot-Product:             76.50    (Threshold: 23.4236)
            F1 with Dot-Product:                   67.00    (Threshold: 19.0095)
            Precision with Dot-Product:            55.93
            Recall with Dot-Product:               83.54
            Average Precision with Dot-Product:    65.89
            Matthews Correlation with Dot-Product: 48.88

            Accuracy with Euclidean-Distance:             67.70     (Threshold: -10.0041)
            F1 with Euclidean-Distance:                   48.60     (Threshold: -0.1876)
            Precision with Euclidean-Distance:            32.13
            Recall with Euclidean-Distance:               99.69
            Average Precision with Euclidean-Distance:    20.52
            Matthews Correlation with Euclidean-Distance: -4.59

            Accuracy with Manhattan-Distance:             67.70     (Threshold: -103.0263)
            F1 with Manhattan-Distance:                   48.60     (Threshold: -0.8532)
            Precision with Manhattan-Distance:            32.13
            Recall with Manhattan-Distance:               99.69
            Average Precision with Manhattan-Distance:    21.05
            Matthews Correlation with Manhattan-Distance: -4.59

            Model Sparsity: Active Dimensions: 61.2, Sparsity Ratio: 0.9980
            '''
            # Print the results
            print(f"Primary metric: {binary_acc_evaluator.primary_metric}")
            # => Primary metric: quora_duplicates_dev_max_ap
            print(f"Primary metric value: {results[binary_acc_evaluator.primary_metric]:.4f}")
            # => Primary metric value: 0.6781
    c
           
     h    || _         t        t              | _        t        
|   ||||||||	      S )N)
sentences1
sentences2labelsname
batch_sizeshow_progress_bar	write_csvsimilarity_fn_names)max_active_dimsr   listsparsity_statssuper__init__)selfr   r   r   r   r   r   r   r   r   	__class__s             /home/chris/cleankitchens-env/lib/python3.12/site-packages/sentence_transformers/sparse_encoder/evaluation/SparseBinaryClassificationEvaluator.pyr   z,SparseBinaryClassificationEvaluator.__init__o   sI      /)$/w!!!/ 3   	
 		
    c                ^    t         |   |       | j                  j                  ddg       y )Nactive_dimssparsity_ratio)r   _append_csv_headerscsv_headersextend)r   r   r   s     r   r#   z7SparseBinaryClassificationEvaluator._append_csv_headers   s+    #$780@ ABr   c                   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       |\| j                  rPt        t         j"                  j%                  || j&                        | j                  d   | j                  d   g       |S )N)modeloutput_pathepochstepsz#Model Sparsity: Active Dimensions: r!   z.1fz, Sparsity Ratio: r"   z.4f)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)	r   r'   r(   r)   r*   metricskeyvaluer   s	           r   r+   z,SparseBinaryClassificationEvaluator.__call__   sE    *$/'"Ku\a"b--335 	?JC'*5zCJ'>D$	? 	t2243F3F		RS--eWeUK1$2E2Em2TUX1YYklpll  AQ  mR  SV  lW  X	
 "t~~[$--8$$]3T5H5HIY5Z[
 r   c                $    t         |   |      S )N)r'   )r   compute_metrices)r   r'   r   s     r   r<   z4SparseBinaryClassificationEvaluator.compute_metrices   s    w'e'44r   c           	         |j                   |f| j                  | j                  dd| j                  d|}|j	                  |      }|j                         D ]#  \  }}| j                  |   j                  |       % |S )NT)r   r   convert_to_sparse_tensorsave_to_cpur   )encoder   r   r   sparsityr,   r   append)r   r'   	sentenceskwargs
embeddingsstatr9   r:   s           r   embed_inputsz0SparseBinaryClassificationEvaluator.embed_inputs   s     "U\\
"44%) 00
 

 ~~j)**, 	3JC$++E2	3r   c                B    |j                   j                  | |||       y )N)r)   step)model_card_dataset_evaluation_metrics)r   r'   r8   r)   rI   s        r   r1   zDSparseBinaryClassificationEvaluator.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   rM   z3SparseBinaryClassificationEvaluator.get_config_dict   s3    g-/+-1-A-AK)*r   )     FTNN)r   	list[str]r   rQ   r   z	list[int]r   strr   intr   boolr   rT   r   z
int | Noner   z?list[Literal['cosine', 'dot', 'euclidean', 'manhattan']] | None)r   rQ   returnNone)NrW   )
r'   r   r(   z
str | Noner)   rS   r*   rS   rU   zdict[str, float])r'   r   rU   zdict[str, dict[str, float]])r'   r   rC   zstr | list[str] | np.ndarrayrU   r
   )r   r   )
r'   r   r8   dict[str, Any]r)   rS   rI   rS   rU   rV   )rU   rX   )__name__
__module____qualname____doc__r   r#   r+   r<   rG   r1   rM   __classcell__)r   s   @r   r   r      s    W| "'&*_c

 
 	

 
 
  
 
 $
 ]
2C
 ce"1;KN\_	*5 0
 
* Z[\"\-;\DG\SV\	\
 r   r   )
__future__r   loggingr4   collectionsr   typingr   r   r    sentence_transformers.evaluationr   sentence_transformers.utilr	   numpynptorchr
   2sentence_transformers.sparse_encoder.SparseEncoderr   	getLoggerrY   r2   r    r   r   <module>rj      sL    "  	 # . . J 9P 
		8	$l*G lr   