Spaces:
Running
Running
Update analyzers/ner_analyzer.py
Browse files- analyzers/ner_analyzer.py +36 -28
analyzers/ner_analyzer.py
CHANGED
|
@@ -2,7 +2,7 @@ from transformers import AutoModelForTokenClassification, AutoTokenizer
|
|
| 2 |
import torch
|
| 3 |
from typing import List, Tuple
|
| 4 |
import logging
|
| 5 |
-
import
|
| 6 |
from .base_analyzer import BaseAnalyzer
|
| 7 |
|
| 8 |
logger = logging.getLogger(__name__)
|
|
@@ -14,6 +14,9 @@ class NERAnalyzer(BaseAnalyzer):
|
|
| 14 |
self.model = AutoModelForTokenClassification.from_pretrained(self.model_name)
|
| 15 |
self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
|
| 16 |
logger.info("Modelo NER e tokenizador carregados com sucesso")
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
def extract_entities(self, text: str) -> List[Tuple[str, str]]:
|
| 19 |
logger.debug("Iniciando extração de entidades com NER")
|
|
@@ -53,20 +56,36 @@ class NERAnalyzer(BaseAnalyzer):
|
|
| 53 |
|
| 54 |
return representatives
|
| 55 |
|
| 56 |
-
def extract_participation_percentage(self, text: str) -> dict:
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
participation_data = {}
|
| 59 |
-
|
| 60 |
-
#
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
logger.debug(f"Dados de participação: {participation_data}")
|
| 71 |
return participation_data
|
| 72 |
|
|
@@ -75,23 +94,12 @@ class NERAnalyzer(BaseAnalyzer):
|
|
| 75 |
entities = self.extract_entities(text)
|
| 76 |
# Extraímos os representantes a partir das entidades
|
| 77 |
representatives = self.extract_representatives(entities)
|
| 78 |
-
# Extraímos os percentuais de participação
|
| 79 |
-
participation_data = self.extract_participation_percentage(text)
|
| 80 |
|
| 81 |
# Associa os representantes aos seus percentuais de participação, se disponível
|
| 82 |
representatives_with_percentage = []
|
| 83 |
for rep in representatives:
|
| 84 |
# Tentando associar o nome do representante ao percentual de participação
|
| 85 |
if rep in participation_data:
|
| 86 |
-
|
| 87 |
-
else:
|
| 88 |
-
representatives_with_percentage.append(rep)
|
| 89 |
-
|
| 90 |
-
return representatives_with_percentage
|
| 91 |
-
|
| 92 |
-
def format_output(self, representatives: List[str]) -> str:
|
| 93 |
-
output = "ANÁLISE DO CONTRATO SOCIAL (NER)\n\n"
|
| 94 |
-
output += "REPRESENTANTES IDENTIFICADOS:\n"
|
| 95 |
-
for rep in representatives:
|
| 96 |
-
output += f"- {rep}\n"
|
| 97 |
-
return output
|
|
|
|
| 2 |
import torch
|
| 3 |
from typing import List, Tuple
|
| 4 |
import logging
|
| 5 |
+
import spacy
|
| 6 |
from .base_analyzer import BaseAnalyzer
|
| 7 |
|
| 8 |
logger = logging.getLogger(__name__)
|
|
|
|
| 14 |
self.model = AutoModelForTokenClassification.from_pretrained(self.model_name)
|
| 15 |
self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
|
| 16 |
logger.info("Modelo NER e tokenizador carregados com sucesso")
|
| 17 |
+
|
| 18 |
+
# Carregar modelo spaCy para processamento de dependências e identificação de entidades
|
| 19 |
+
self.nlp = spacy.load("pt_core_news_lg")
|
| 20 |
|
| 21 |
def extract_entities(self, text: str) -> List[Tuple[str, str]]:
|
| 22 |
logger.debug("Iniciando extração de entidades com NER")
|
|
|
|
| 56 |
|
| 57 |
return representatives
|
| 58 |
|
| 59 |
+
def extract_participation_percentage(self, text: str, representatives: List[str]) -> dict:
|
| 60 |
+
"""
|
| 61 |
+
Identifica os percentuais de participação no texto e associa ao representante mais próximo.
|
| 62 |
+
"""
|
| 63 |
+
# Utilizando o spaCy para análise de dependências e encontrar a relação entre porcentagens e nomes
|
| 64 |
+
doc = self.nlp(text)
|
| 65 |
participation_data = {}
|
| 66 |
+
|
| 67 |
+
# Iterar sobre o texto para buscar percentuais e associá-los ao nome mais próximo
|
| 68 |
+
for token in doc:
|
| 69 |
+
# Verificar se o token é um percentual (%)
|
| 70 |
+
if token.text.endswith('%'):
|
| 71 |
+
percentage = token.text.replace('%', '').strip()
|
| 72 |
+
try:
|
| 73 |
+
percentage = float(percentage.replace(',', '.')) # Garantir que o valor seja numérico
|
| 74 |
+
except ValueError:
|
| 75 |
+
continue
|
| 76 |
+
|
| 77 |
+
# Verificar os nomes próximos ao percentual
|
| 78 |
+
left_context = [w.text for w in token.lefts]
|
| 79 |
+
right_context = [w.text for w in token.rights]
|
| 80 |
+
context = left_context + right_context
|
| 81 |
+
|
| 82 |
+
# Procurar por um representante no contexto
|
| 83 |
+
for rep in representatives:
|
| 84 |
+
# Se o nome do representante estiver nas palavras ao redor do percentual, associamos
|
| 85 |
+
if any(rep.lower() in word.lower() for word in context):
|
| 86 |
+
participation_data[rep] = percentage
|
| 87 |
+
break
|
| 88 |
+
|
| 89 |
logger.debug(f"Dados de participação: {participation_data}")
|
| 90 |
return participation_data
|
| 91 |
|
|
|
|
| 94 |
entities = self.extract_entities(text)
|
| 95 |
# Extraímos os representantes a partir das entidades
|
| 96 |
representatives = self.extract_representatives(entities)
|
| 97 |
+
# Extraímos os percentuais de participação e associamos aos representantes
|
| 98 |
+
participation_data = self.extract_participation_percentage(text, representatives)
|
| 99 |
|
| 100 |
# Associa os representantes aos seus percentuais de participação, se disponível
|
| 101 |
representatives_with_percentage = []
|
| 102 |
for rep in representatives:
|
| 103 |
# Tentando associar o nome do representante ao percentual de participação
|
| 104 |
if rep in participation_data:
|
| 105 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|