Spaces:
Sleeping
Sleeping
| # abstractive.py | |
| """ | |
| Módulo de resúmenes 'abstractive.py' | |
| Contiene implementaciones de diferentes técnicas de resumen de texto: | |
| - TF-IDF Summarizer | |
| - TextRank Summarizer | |
| - Combined Summarizer (que combina TF-IDF y TextRank para extraer palabras clave) | |
| - BERT Summarizer (extractivo basado en un modelo BERT preentrenado) | |
| """ | |
| import numpy as np | |
| import networkx as nx | |
| from typing import List | |
| from sklearn.feature_extraction.text import TfidfVectorizer | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| from summarizer import Summarizer | |
| class TFIDFSummarizer: | |
| """Genera resúmenes usando el modelo TF-IDF.""" | |
| def summarize(sentences: List[str], preprocessed_sentences: List[str], num_sentences: int = 1) -> str: | |
| """ | |
| Genera un resumen basado en TF-IDF seleccionando las oraciones mejor puntuadas. | |
| :param sentences: Lista de oraciones originales (sin procesar). | |
| :param preprocessed_sentences: Lista de oraciones preprocesadas (por ejemplo, tokenizadas o normalizadas). | |
| :param num_sentences: Número de oraciones a devolver en el resumen. | |
| :return: Un string que contiene el resumen formado por las oraciones más relevantes. | |
| """ | |
| vectorizer = TfidfVectorizer() | |
| tfidf_matrix = vectorizer.fit_transform(preprocessed_sentences) | |
| sentence_scores = np.sum(tfidf_matrix.toarray(), axis=1) | |
| ranked_indices = np.argsort(sentence_scores)[::-1] | |
| selected = [sentences[i] for i in ranked_indices[:num_sentences]] | |
| return ' '.join(selected) | |
| class TextRankSummarizer: | |
| """Genera resúmenes usando el algoritmo TextRank.""" | |
| def summarize(sentences: List[str], preprocessed_sentences: List[str], num_sentences: int = 1) -> str: | |
| """ | |
| Genera un resumen usando el algoritmo de grafos TextRank. | |
| :param sentences: Lista de oraciones originales. | |
| :param preprocessed_sentences: Lista de oraciones preprocesadas. | |
| :param num_sentences: Número de oraciones a devolver en el resumen. | |
| :return: Un string que contiene el resumen. | |
| """ | |
| vectorizer = TfidfVectorizer() | |
| tfidf_matrix = vectorizer.fit_transform(preprocessed_sentences) | |
| similarity_matrix = cosine_similarity(tfidf_matrix) | |
| nx_graph = nx.from_numpy_array(similarity_matrix) | |
| scores = nx.pagerank(nx_graph) | |
| # Ordena los nodos (oraciones) por puntaje descendente | |
| ranked_indices = sorted(((scores[node], node) for node in nx_graph.nodes), reverse=True) | |
| selected = [sentences[i] for _, i in ranked_indices[:num_sentences]] | |
| return ' '.join(selected) | |
| class CombinedSummarizer: | |
| """Genera resúmenes combinando palabras clave TF-IDF y TextRank.""" | |
| def __init__(self, top_n_keywords: int = 10): | |
| """ | |
| :param top_n_keywords: Número de palabras clave a extraer de cada método (TF-IDF y TextRank). | |
| """ | |
| self.top_n_keywords = top_n_keywords | |
| def extract_keywords_tfidf(self, preprocessed_sentences: List[str]) -> List[str]: | |
| """ | |
| Extrae palabras clave basadas en TF-IDF. | |
| :param preprocessed_sentences: Lista de oraciones preprocesadas. | |
| :return: Lista con las palabras clave más relevantes según TF-IDF. | |
| """ | |
| vectorizer = TfidfVectorizer() | |
| tfidf_matrix = vectorizer.fit_transform(preprocessed_sentences) | |
| tfidf_scores = zip(vectorizer.get_feature_names_out(), tfidf_matrix.toarray().sum(axis=0)) | |
| sorted_scores = sorted(tfidf_scores, key=lambda x: x[1], reverse=True) | |
| return [word for word, _ in sorted_scores[:self.top_n_keywords]] | |
| def extract_keywords_textrank(self, preprocessed_sentences: List[str]) -> List[str]: | |
| """ | |
| Extrae palabras clave basadas en TextRank (a través de la co-ocurrencia de palabras). | |
| :param preprocessed_sentences: Lista de oraciones preprocesadas. | |
| :return: Lista con las palabras clave más relevantes según TextRank. | |
| """ | |
| words = ' '.join(preprocessed_sentences).split() | |
| co_occurrence_graph = nx.Graph() | |
| for i in range(len(words) - 1): | |
| word_pair = (words[i], words[i + 1]) | |
| if co_occurrence_graph.has_edge(*word_pair): | |
| co_occurrence_graph[word_pair[0]][word_pair[1]]['weight'] += 1 | |
| else: | |
| co_occurrence_graph.add_edge(word_pair[0], word_pair[1], weight=1) | |
| ranks = nx.pagerank(co_occurrence_graph, weight='weight') | |
| sorted_ranks = sorted(ranks.items(), key=lambda x: x[1], reverse=True) | |
| return [word for word, _ in sorted_ranks[:self.top_n_keywords]] | |
| def combined_keywords(self, preprocessed_sentences: List[str]) -> List[str]: | |
| """ | |
| Combina las palabras clave obtenidas tanto por TF-IDF como por TextRank | |
| y devuelve la intersección de ambas listas. | |
| :param preprocessed_sentences: Lista de oraciones preprocesadas. | |
| :return: Lista con las palabras clave en común (intersección). | |
| """ | |
| tfidf_keywords = self.extract_keywords_tfidf(preprocessed_sentences) | |
| textrank_keywords = self.extract_keywords_textrank(preprocessed_sentences) | |
| return list(set(tfidf_keywords) & set(textrank_keywords)) | |
| def summarize(self, sentences: List[str], preprocessed_sentences: List[str], num_sentences: int = 1) -> str: | |
| """ | |
| Genera un resumen basado en la frecuencia de palabras clave combinadas (TF-IDF & TextRank). | |
| :param sentences: Lista de oraciones originales. | |
| :param preprocessed_sentences: Lista de oraciones preprocesadas. | |
| :param num_sentences: Número de oraciones a devolver en el resumen. | |
| :return: Un string con las oraciones más relevantes. | |
| """ | |
| keywords = self.combined_keywords(preprocessed_sentences) | |
| sentence_scores = [] | |
| for i, sentence in enumerate(preprocessed_sentences): | |
| score = sum(1 for word in sentence.split() if word in keywords) | |
| sentence_scores.append((score, i)) | |
| # Ordena las oraciones por la cantidad de palabras clave presentes | |
| ranked_sentences = sorted(sentence_scores, key=lambda x: x[0], reverse=True) | |
| selected = [sentences[i] for _, i in ranked_sentences[:num_sentences]] | |
| return ' '.join(selected) | |
| class BERTSummarizer: | |
| def __init__(self): | |
| self.model = Summarizer() | |
| def summarize(self, text, num_sentences): | |
| return self.model(text, num_sentences=num_sentences) | |