File size: 3,264 Bytes
efccf51
 
 
dcdbcfb
 
efccf51
dcdbcfb
efccf51
dcdbcfb
 
efccf51
dcdbcfb
 
 
 
efccf51
 
dcdbcfb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
efccf51
dcdbcfb
 
 
 
 
 
 
 
 
 
 
 
efccf51
dcdbcfb
efccf51
dcdbcfb
 
efccf51
 
dcdbcfb
efccf51
dcdbcfb
efccf51
dcdbcfb
efccf51
 
dcdbcfb
 
efccf51
dcdbcfb
 
 
 
 
efccf51
 
 
 
 
 
 
dcdbcfb
 
efccf51
dcdbcfb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# modules/text_analysis/stopwords.py
import spacy
from typing import Set, List
import unicodedata
import logging

logger = logging.getLogger(__name__)

# Símbolos universales (Preservado del original)
SYMBOLS_AND_NUMBERS = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '.', ',', ';', ':', '!', '¡', '?', '¿', '"', "'",
    '+', '-', '*', '/', '=', '<', '>', '%', '(', ')', 
    '[', ']', '{', '}', '@', '#', '$', '€', '&', '_', 
    '|', '\\', '•', '·', '…', '©', '®', '™'
}

# --- FUNCIÓN ADICIONAL INTERNA (Documentación: Manejo de acentos) ---
def _normalize_caseless(text: str) -> str:
    """Función interna para comparar palabras ignorando tildes y mayúsculas."""
    text = text.lower()
    return ''.join(
        c for c in unicodedata.normalize('NFD', text)
        if unicodedata.category(c) != 'Mn'
    )

def get_custom_stopwords(lang_code: str) -> Set[str]:
    """

    NOMBRE PRESERVADO. Ahora incluye diccionarios para ES, EN, FR, PT.

    """
    stops_by_lang = {
        'es': {'el', 'la', 'un', 'una', 'y', 'e', 'o', 'u', 'pero', 'con', 'por', 'para'},
        'en': {'the', 'a', 'an', 'and', 'but', 'if', 'or', 'with', 'for', 'at', 'by'},
        'fr': {'le', 'la', 'les', 'un', 'une', 'des', 'et', 'ou', 'mais', 'dans'},
        'pt': {'o', 'a', 'os', 'as', 'um', 'uma', 'e', 'mas', 'ou', 'com', 'por'}
    }
    return stops_by_lang.get(lang_code, stops_by_lang['en'])

def get_stopwords_for_spacy(lang_code: str, nlp) -> Set[str]:
    """

    NOMBRE PRESERVADO. Ahora normaliza las stopwords de spaCy para que 

    filtren palabras con tilde correctamente.

    """
    spacy_stops = nlp.Defaults.stop_words if hasattr(nlp.Defaults, 'stop_words') else set()
    custom_stops = get_custom_stopwords(lang_code)
    combined = spacy_stops.union(custom_stops)
    # Normalizamos todas para una comparación ciega a tildes
    return {_normalize_caseless(word) for word in combined}

def process_text(text: str, nlp, lang_code: str) -> List[str]:
    """

    NOMBRE PRESERVADO. Lógica mejorada: usa normalización para que 'Análisis' 

    sea filtrado si 'analisis' está en la lista de stopwords.

    """
    try:
        if not text: return []
        doc = nlp(text)
        stopwords = get_stopwords_for_spacy(lang_code, nlp)
        processed_tokens = []
        
        for token in doc:
            lemma = token.lemma_.lower()
            # Normalizamos el lema para la comparación
            norm_lemma = _normalize_caseless(lemma)
            
            if (norm_lemma not in stopwords and 
                not token.is_punct and 
                not token.is_space and 
                lemma not in SYMBOLS_AND_NUMBERS and
                len(norm_lemma) > 1):
                processed_tokens.append(lemma)
        return processed_tokens
    except Exception as e:
        logger.error(f"Error en process_text: {str(e)}")
        return []

def clean_text(text: str) -> str:
    """NOMBRE PRESERVADO. Limpia espacios y símbolos manteniendo caracteres latinos."""
    if not text: return ""
    cleaned = ''.join(char for char in text if char not in SYMBOLS_AND_NUMBERS)
    return ' '.join(cleaned.split()).strip()