
    Ng(1                        d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ e
rd dlmZ  ej        e          Z G d	 d
e          ZdS )    )annotationsN)defaultdict)nullcontext)TYPE_CHECKING)SentenceEvaluator)paraphrase_mining)SentenceTransformerc                  `     e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 d*d+ fdZ	 d,d-d(Zed)             Z xZS ).ParaphraseMiningEvaluatora  
    Given a large set of sentences, this evaluator performs paraphrase (duplicate) mining and
    identifies the pairs with the highest similarity. It compare the extracted paraphrase pairs
    with a set of gold labels and computes the F1 score.

    Example:
        ::

            from datasets import load_dataset
            from sentence_transformers.SentenceTransformer import SentenceTransformer
            from sentence_transformers.evaluation import ParaphraseMiningEvaluator

            # Load a model
            model = SentenceTransformer('all-mpnet-base-v2')

            # Load the Quora Duplicates Mining dataset
            questions_dataset = load_dataset("sentence-transformers/quora-duplicates-mining", "questions", split="dev")
            duplicates_dataset = load_dataset("sentence-transformers/quora-duplicates-mining", "duplicates", split="dev")

            # Create a mapping from qid to question & a list of duplicates (qid1, qid2)
            qid_to_questions = dict(zip(questions_dataset["qid"], questions_dataset["question"]))
            duplicates = list(zip(duplicates_dataset["qid1"], duplicates_dataset["qid2"]))

            # Initialize the paraphrase mining evaluator
            paraphrase_mining_evaluator = ParaphraseMiningEvaluator(
                sentences_map=qid_to_questions,
                duplicates_list=duplicates,
                name="quora-duplicates-dev",
            )
            results = paraphrase_mining_evaluator(model)
            '''
            Paraphrase Mining Evaluation of the model on the quora-duplicates-dev dataset:
            Number of candidate pairs: 250564
            Average Precision: 56.51
            Optimal threshold: 0.8325
            Precision: 52.76
            Recall: 59.19
            F1: 55.79
            '''
            print(paraphrase_mining_evaluator.primary_metric)
            # => "quora-duplicates-dev_average_precision"
            print(results[paraphrase_mining_evaluator.primary_metric])
            # => 0.5650940787776353
    NF  順   d       Tsentences_mapdict[str, str]duplicates_listlist[tuple[str, str]]duplicates_dictdict[str, dict[str, bool]]add_transitive_closureboolquery_chunk_sizeintcorpus_chunk_size	max_pairstop_kshow_progress_bar
batch_sizenamestr	write_csvtruncate_dim
int | Nonec           
        t                                                       g | _        g | _        |                                D ]9\  }}| j                            |           | j                            |           :|| _        |	| _        |
| _        || _	        || _
        || _        || _        || _        ||nt          d           | _        |0|D ]-\  }}||v r$||v r d| j        |         |<   d| j        |         |<   .|r|                     | j                  | _        t#                      }| j        D ]q}| j        |         D ]a}||v r[||v rW| j        |         |         s| j        |         |         r1|                    t'          t)          ||g                               brt+          |          | _        |rd|z   }d|z   dz   | _        g d| _        || _        d| _        dS )	a	  
        Initializes the ParaphraseMiningEvaluator.

        Args:
            sentences_map (Dict[str, str]): A dictionary that maps sentence-ids to sentences.
                For example, sentences_map[id] => sentence.
            duplicates_list (List[Tuple[str, str]], optional): A list with id pairs [(id1, id2), (id1, id5)]
                that identifies the duplicates / paraphrases in the sentences_map. Defaults to None.
            duplicates_dict (Dict[str, Dict[str, bool]], optional): A default dictionary mapping [id1][id2]
                to true if id1 and id2 are duplicates. Must be symmetric, i.e., if [id1][id2] => True,
                then [id2][id1] => True. Defaults to None.
            add_transitive_closure (bool, optional): If true, it adds a transitive closure,
                i.e. if dup[a][b] and dup[b][c], then dup[a][c]. Defaults to False.
            query_chunk_size (int, optional): To identify the paraphrases, the cosine-similarity between
                all sentence-pairs will be computed. As this might require a lot of memory, we perform
                a batched computation. query_chunk_size sentences will be compared against up to
                corpus_chunk_size sentences. In the default setting, 5000 sentences will be grouped
                together and compared up-to against 100k other sentences. Defaults to 5000.
            corpus_chunk_size (int, optional): The corpus will be batched, to reduce the memory requirement.
                Defaults to 100000.
            max_pairs (int, optional): We will only extract up to max_pairs potential paraphrase candidates.
                Defaults to 500000.
            top_k (int, optional): For each query, we extract the top_k most similar pairs and add it to a sorted list.
                I.e., for one sentence we cannot find more than top_k paraphrases. Defaults to 100.
            show_progress_bar (bool, optional): Output a progress bar. Defaults to False.
            batch_size (int, optional): Batch size for computing sentence embeddings. Defaults to 16.
            name (str, optional): Name of the experiment. Defaults to "".
            write_csv (bool, optional): Write results to CSV file. Defaults to True.
            truncate_dim (Optional[int], optional): The dimension to truncate sentence embeddings to.
                `None` uses the model's current truncation dimension. Defaults to None.
        Nc                 *    t          t                    S )N)r   r        v/var/www/html/ai-engine/env/lib/python3.11/site-packages/sentence_transformers/evaluation/ParaphraseMiningEvaluator.py<lambda>z4ParaphraseMiningEvaluator.__init__.<locals>.<lambda>   s    bmnrbsbs r)   T_paraphrase_mining_evaluationz_results.csv)epochsteps	precisionrecallf1	thresholdaverage_precisionr4   )super__init__	sentencesidsitemsappendr!   r   r    r   r   r   r   r$   r   
duplicatesr   setaddtuplesortedlentotal_num_duplicatescsv_filecsv_headersr#   primary_metric)selfr   r   r   r   r   r   r   r   r   r    r!   r#   r$   idsentenceid1id2positive_key_pairskey1key2	__class__s                        r*   r6   z"ParaphraseMiningEvaluator.__init__A   s=   ^ 	)//11 	  	 LBN!!(+++HOOB	!2$ 0!2"
(-<-H//kZsZsNtNt&+ 5 5S-''C=,@,@04DOC(-04DOC(- " 	K"99$/JJDO UUO 	H 	HD- H HM))--.t4 .8<8Md8S . '**5t1E1E+F+FGGGH %((:$;$;! 	:D;dB^Slll"1r)   modelr	   output_pathr.   r/   returndict[str, float]c                   |dk    r|dk    rd| }nd| d| d}nd}| j         |d| j          dz  }t                              d	| j         d
| d           | j         t	                      n|                    | j                   5  t          || j        | j        | j	        | j
        | j        | j        | j                  }d d d            n# 1 swxY w Y   t                              dt          t          |                    z              dx}}d}	dx}
x}}d}t!          t          |                    D ]}||         \  }}}| j        |         }| j        |         }|dz  }| j        |         |         s| j        |         |         rt|dz  }||z  }|| j        z  }d|z  |z  ||z   z  }||z  }||
k    rG|}
|}|}||         d         |t)          |dz   t          |          dz
                     d         z   dz  }	|| j        z  }t                              d|dz  d           t                              d|	d           t                              d|dz  d           t                              d|dz  d           t                              d|
dz  dd           || j        rt,          j                            || j                  }t,          j                            |          svt7          |ddd          5 }t9          j        |          }|                    | j                   |                    |||||
|	|g           d d d            n# 1 swxY w Y   n[t7          |ddd          5 }t9          j        |          }|                    |||||
|	|g           d d d            n# 1 swxY w Y   ||
|||	d}|                      || j                  }| !                    ||           |S )NrN   z after epoch z
 in epoch z after z stepsr   z (truncated to )z1Paraphrase Mining Evaluation of the model on the z dataset:zNumber of candidate pairs: r         zAverage Precision: r   z.2fzOptimal threshold: z.4fzPrecision: zRecall: zF1: 
wzutf-8)newlinemodeencodinga)r4   r2   r0   r1   r3   )"r$   loggerinfor!   r   truncate_sentence_embeddingsr   r7   r   r    r   r   r   r   r"   r@   ranger8   r;   rA   minr#   ospathjoinrB   isfileopencsvwriterwriterowrC   prefix_name_to_metrics store_metrics_in_model_card_data)rE   rO   rP   r.   r/   out_txt
pairs_list	n_extract	n_correctr3   best_f1best_recallbest_precisionr4   idxscoreijrH   rI   r0   r1   r2   csv_pathfri   metricss                              r*   __call__z"ParaphraseMiningEvaluator.__call__   sZ    B;;{{1%11BuBBUBBBG(=):====Ge	ee[beeefff #/7[]]]U=_=_`d`q=r=r 
	 
	*&%&
	 	J
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 	1CJ4H4HHIII !"!	I	1222+Z)) 	l 	lC$S/KE1a(1+C(1+C NIs#C( 
lDOC,@,E 
lQ	%	1	"T%>>]V+y6/AB!Y.!<< G%.N"(K!+C!3jS1WcR\oo`aNaAbAb6cde6f!fjk kI-0IIG*;c*AGGGHHH9)999:::<.3"6<<<===6{S066677707S=0000111"t~"w||K??H7>>(++ x(BS7KKK xq Z]]FOOD$4555OOUE>;PWYbdu$vwwwx x x x x x x x x x x x x x x
 (BS7KKK xq Z]]FOOUE>;PWYbdu$vwwwx x x x x x x x x x x x x x x
 "3'!"
 
 --gtyAA--eW===s7   	:CCCAM))M-0M-1OO	O	c                6   t                      }t          |                                           D ]g}||vr_t                      }|                    |           t          | |                   }t	          |          dk    r\|                    d          }||vr0|                    |           |                    | |                    t	          |          dk    \t          |          }t          t	          |          dz
            D ]}t          |dz   t	          |                    D ]f}d| ||                  ||         <   d| ||                  ||         <   |                    ||                    |                    ||                    gi| S )Nr   rV   T)r<   listkeysr=   r@   popextendra   )graphnodes_visitedr]   connected_subgraph_nodesneighbor_nodes_queuenoderv   rw   s           r*   r   z0ParaphraseMiningEvaluator.add_transitive_closure   s   ejjll## 	G 	GA%%+.55((,,Q/// (,E!H~~$.//!33/33A66D#;;;044T:::,33E$K@@@	 .//!33 ,00H+I+I(s#;<<q@AA G GA"1q5#.F*G*GHH G GZ^6q9:;STU;VWZ^6q9:;STU;VW%))*B1*EFFF%))*B1*EFFFFG r)   )NNFr   r   r   r   Fr   r   TN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r!   r"   r#   r   r$   r%   )NrN   rN   )
rO   r	   rP   r"   r.   r   r/   r   rQ   rR   )	__name__
__module____qualname____doc__r6   r{   staticmethodr   __classcell__)rM   s   @r*   r   r      s        + +` 266:', $!'"'#']2 ]2 ]2 ]2 ]2 ]2 ]2@ bdU U U U Un   \    r)   r   )
__future__r   rh   loggingrc   collectionsr   
contextlibr   typingr   2sentence_transformers.evaluation.SentenceEvaluatorr   sentence_transformers.utilr   )sentence_transformers.SentenceTransformerr	   	getLoggerr   r^   r   r(   r)   r*   <module>r      s    " " " " " " 



  				 # # # # # # " " " " " "             P P P P P P 8 8 8 8 8 8 NMMMMMM		8	$	$} } } } } 1 } } } } }r)   