
    Wi-&                     ~    d dl Zd dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZ d dlmZ d dlmZ d dlmZ  G d d	e      Zy)
    N)version)
csr_matrix)MappingListTupleUnion)cosine_similarity)BaseRepresentation)__version__c                      e Zd Z	 	 	 	 	 ddededededef
dZ	 ddej                  d	ed
ee	e
ee	ef      f   dej                  dee	e
ee	ef      f   f
dZd	ed
ee	e
ee	ef      f   dee	e
ee	ef      f   fdZ	 dd
ee	e
ee	ef      f   de
e	   de
e
e      dej                  deej                  e
e	   f   f
dZde
e	   d
ee	e
ee	ef      f   dej                  dee	e
ee	ef      f   fdZy)KeyBERTInspiredtop_n_wordsnr_repr_docs
nr_samplesnr_candidate_wordsrandom_statec                 J    || _         || _        || _        || _        || _        y)a  Use a KeyBERT-like model to fine-tune the topic representations.

        The algorithm follows KeyBERT but does some optimization in
        order to speed up inference.

        The steps are as follows. First, we extract the top n representative
        documents per topic. To extract the representative documents, we
        randomly sample a number of candidate documents per cluster
        which is controlled by the `nr_samples` parameter. Then,
        the top n representative documents  are extracted by calculating
        the c-TF-IDF representation for the  candidate documents and finding,
        through cosine similarity, which are closest to the topic c-TF-IDF representation.
        Next, the top n words per topic are extracted based on their
        c-TF-IDF representation, which is controlled by the `nr_repr_docs`
        parameter.

        Then, we extract the embeddings for words and representative documents
        and create topic embeddings by averaging the representative documents.
        Finally, the most similar words to each topic are extracted by
        calculating the cosine similarity between word and topic embeddings.

        Arguments:
            top_n_words: The top n words to extract per topic.
            nr_repr_docs: The number of representative documents to extract per cluster.
            nr_samples: The number of candidate documents to extract per cluster.
            nr_candidate_words: The number of candidate words per cluster.
            random_state: The random state for randomly sampling candidate documents.

        Usage:

        ```python
        from bertopic.representation import KeyBERTInspired
        from bertopic import BERTopic

        # Create your representation model
        representation_model = KeyBERTInspired()

        # Use the representation model in BERTopic on top of the default pipeline
        topic_model = BERTopic(representation_model=representation_model)
        ```
        N)r   r   r   r   r   )selfr   r   r   r   r   s         l/home/sietch6/trending-topics-pipeline/venv/lib/python3.12/site-packages/bertopic/representation/_keybert.py__init__zKeyBERTInspired.__init__   s,    b '($"4(    N	documentsc_tf_idftopics
embeddingsreturnc                 :   |j                  |||| j                  | j                        \  }}}}d}	|%t        j                  |      D 
cg c]  }
||
   	 }	}
| j                  |||      }| j                  |||||	      \  }}| j                  |||      }|S c c}
w )a  Extract topics.

        Arguments:
            topic_model: A BERTopic model
            documents: All input documents
            c_tf_idf: The topic c-TF-IDF representation
            topics: The candidate topics as calculated with c-TF-IDF
            embeddings: Pre-trained document embeddings. These can be used
                        instead of an embedding model

        Returns:
            updated_topics: Updated topic representations
        N)_extract_representative_docsr   r   npconcatenate_extract_candidate_words_extract_embeddings_extract_top_words)r   topic_modelr   r   r   r   _representative_docsrepr_doc_indicesrepr_embeddingsindex
sim_matrixwordsupdated_topicss                 r   extract_topicszKeyBERTInspired.extract_topicsD   s    , 7B6^6^i$:K:K7
3 0!
 !>@nnM]>^_Uz%0_O_ ..{HfM !44!46F

E 00
K `s   
Bc                    t        t        |j                                     D cg c]  }t        |       }}t	        j
                  t              t	        j
                  d      k\  r|j                  j                         }n|j                  j                         }|j                  || j                        }|j                  ||      }t        j                  |d      }	t        j                  ||	d      }t        j                  ||	d      }t!        |      D 
ci c]E  \  }
}|t#        ||
   ddd   ||
   ddd         D cg c]  \  }}||dkD  r||   |fnd c}}G }}}}
}|j%                         D ci c]$  \  }}|t'        t#        |d| j                          & }}}|S c c}w c c}}w c c}}}}
w c c}}w )aG  For each topic, extract candidate words based on the c-TF-IDF
        representation.

        Arguments:
            topic_model: A BERTopic model
            c_tf_idf: The topic c-TF-IDF representation
            topics: The top words per topic

        Returns:
            topics: The `self.top_n_words` per topic
        z1.0.0   axisNr   ) gh㈵>)sortedlistkeysintr   parsesklearn_versionvectorizer_modelget_feature_names_outget_feature_names_top_n_idx_sparser   _top_n_values_sparser   argsorttake_along_axis	enumeratezipitemsnext)r   r$   r   r   labellabelsr+   indicesscoressorted_indicesr)   
word_indexscorevaluess                 r   r!   z(KeyBERTInspired._extract_candidate_wordsp   s   " +1fkkm1D*EF#e*FF ==)W]]7-CC00FFHE00BBDE//$:Q:QR11(GDFA.$$Wn1E##FNC !*& 1
 

 u	 ),WU^DbD-A6%=QUSUQUCV)W%J /9.DQRz"E*Xee 
 
 ]c\h\h\jk=5RX%c6*CD,C,C#DEFFkk3 G"
 ls#   F1!*F<
F6%F<
)G6F<
r&   r'   r(   c           
      ^   ||j                  |dd      }|D cg c]%  }t        j                  ||d   |d   dz    d      ' }}t        t	        |j                         D 	cg c]  }|D ]  }	|	  c}	}            }
|j                  |
dd      }t        ||      }||
fS c c}w c c}	}w )a;  Extract the representative document embeddings and create topic embeddings.
        Then extract word embeddings and calculate the cosine similarity between topic
        embeddings and the word embeddings. Topic embeddings are the average of
        representative document embeddings.

        Arguments:
            topic_model: A BERTopic model
            topics: The top words per topic
            representative_docs: A flat list of representative documents
            repr_doc_indices: The indices of representative documents
                              that belong to each topic
            repr_embeddings: Embeddings of respective representative_docs

        Returns:
            sim: The similarity matrix between word and topic embeddings
            vocab: The complete vocabulary of input documents
        documentF)methodverboser   r2   r/   r0   )r"   r   meanr5   setrL   r	   )r   r$   r   r&   r'   r(   itopic_embeddingsr+   wordvocabword_embeddingssims                r   r"   z#KeyBERTInspired._extract_embeddings   s    4 ")==>QZdns=tOXhiSTBGGOAaD1R519$EANii SFMMON5N$N$NOP%99%
\a9b 0/BEz j Os   *B$$B)rV   rX   c                 &   t        t        |j                                     D cg c]  }t        |       }}i }t	        |      D ]  \  }}||   D 	cg c]  }	|j                  |	       }
}	|dd|
f   |   }t        j                  |      | j                   d D cg c]  }|
|   	 }}t        t        j                  |      | j                   d |      D cg c]  \  }}||   |f c}}ddd   ||<    |S c c}w c c}	w c c}w c c}}w )a  Extract the top n words per topic based on the
        similarity matrix between topics and words.

        Arguments:
            vocab: The complete vocabulary of input documents
            labels: All topic labels
            topics: The top words per topic
            sim: The similarity matrix between word and topic embeddings

        Returns:
            updated_topics: The updated topic representations
        Nr2   )r4   r5   r6   r7   rA   r)   r   r?   r   rB   sort)r   rV   r   rX   rE   rF   r,   rS   topicrU   rG   rL   r)   word_indicesvals                  r   r#   z"KeyBERTInspired._extract_top_words   s   $ +1fkkm1D*EF#e*FF!&) 	HAu5;E]CTu{{4(CGCG_Q'F8:

68JDL\L\K\K^8_`uGEN`L`69"''&/4K[K[J[J]:^`l6m%(2Uus#%d%N5!		  G D`%s   C>DDD)
      i  d   *   )N)__name__
__module____qualname__r7   r   pd	DataFramer   r   strr   r   floatr   ndarrayr-   r!   r   r"   r#    r   r   r   r      s    "%5)5) 5) 	5)
  5) 5)z "&* <<* 	*
 T%U
"3445* JJ* 
d5e,--	.*X* * T%U
"3445	*
 
d5e,--	.*d '+$ T%U
"3445$ "#Y	$
 tCy/$ $ 
rzz49$	%$LCy T%U
"3445 ZZ	
 
d5e,--	.r   r   )numpyr   pandasre   	packagingr   scipy.sparser   typingr   r   r   r   sklearn.metrics.pairwiser	   bertopic.representation._baser
   sklearnr   r9   r   rj   r   r   <module>rs      s/       # . . 6 < 2R( Rr   