""" Exemplo de uso do Radar Legislativo LGBTQIA+ Sistema de classificação de Projetos de Lei por Ensemble Híbrido """ from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification import re print("🏳️‍🌈 Radar Legislativo LGBTQIA+ - Exemplo de Uso\n") # ======================================== # 1. CARREGAR MODELOS # ======================================== print("📦 Carregando modelos...") # Radar Social LGBTQIA+ V2.1 print(" Carregando Radar Social...") radar = pipeline( "text-classification", model="Veronyka/radar-social-lgbtqia-v2.1", device=-1 # CPU (-1) ou GPU (0) ) # AzMina/QuiterIA (com tokenizer explícito) print(" Carregando AzMina...") try: tokenizer = AutoTokenizer.from_pretrained("neuralmind/bert-base-portuguese-cased") azmina_model = AutoModelForSequenceClassification.from_pretrained("azmina/ia-feminista-bert-posicao") azmina = pipeline( "text-classification", model=azmina_model, tokenizer=tokenizer, device=-1 ) print(" ✅ Ambos os modelos carregados com sucesso!\n") except Exception as e: print(f" ⚠️ Erro ao carregar AzMina: {e}") print(" ℹ️ Sistema funcionará sem AzMina\n") azmina = None # ======================================== # 2. DEFINIR KEYWORDS E PADRÕES # ======================================== KEYWORDS_DESFAVORAVEIS = [ r"proíbe.*gênero", r"ideologia de gênero", r"sexo biológico", r"terapia.*conversão", r"cura.*gay", r"família.*tradicional", r"veda.*gênero", r"restringe.*gênero" ] PADROES_ALTA_PRIORIDADE = [ r"(proíbe|veda).*(uso|exibição).*(símbolo|símbolos).*religios.*(parada|lgbt)", r"(impede|proíbe).*(menor|criança).*(evento|parada).*(lgbt|comunidade)" ] PADROES_RESTRITIVOS = [ r"define.*(sexo|gênero).*biolog", r"(proíbe|proibição).*(ensino|divulgação).*gênero", r"exclusivamente.*(homem|mulher).*(cis|biologic)" ] # ======================================== # 3. FUNÇÃO DE CLASSIFICAÇÃO # ======================================== def classificar_pl(ementa: str) -> dict: """ Classifica uma PL usando Ensemble Híbrido Args: ementa: Texto da ementa da PL Returns: dict com classificação, score e detalhes """ # 1. Radar Social (20%) radar_result = radar(ementa, truncation=True, max_length=256) label_radar = radar_result[0]['label'] score_radar_raw = radar_result[0]['score'] score_radar = score_radar_raw if label_radar == 'HATE' else 1 - score_radar_raw # 2. AzMina (15% ou 0% se não disponível) if azmina: azmina_result = azmina(ementa, truncation=True, max_length=256) label_azmina = azmina_result[0]['label'] score_azmina_raw = azmina_result[0]['score'] score_azmina = 1 - score_azmina_raw if label_azmina == 'LABEL_1' else score_azmina_raw peso_azmina = 0.15 else: score_azmina = 0.5 peso_azmina = 0.0 # 3. Keywords (35% ou 40% se AzMina não disponível) ementa_lower = ementa.lower() kw_desfav = sum(1 for kw in KEYWORDS_DESFAVORAVEIS if re.search(kw, ementa_lower, re.IGNORECASE)) score_keywords = min(kw_desfav / 5, 1.0) # Normalizado (max 5 keywords) peso_keywords = 0.40 if not azmina else 0.35 # 4. Padrões (30% ou 40% se AzMina não disponível) matches_alta = sum(1 for padrao in PADROES_ALTA_PRIORIDADE if re.search(padrao, ementa_lower, re.IGNORECASE)) matches_normais = sum(1 for padrao in PADROES_RESTRITIVOS if re.search(padrao, ementa_lower, re.IGNORECASE)) if matches_alta > 0: score_padroes = 0.99 # Score muito alto para padrões de alta prioridade else: score_padroes = min(matches_normais / 3, 1.0) # Normalizado (max 3 padrões) peso_padroes = 0.40 if not azmina else 0.30 peso_radar = 0.20 # 5. Ensemble (soma ponderada) score_final = ( peso_radar * score_radar + peso_azmina * score_azmina + peso_keywords * score_keywords + peso_padroes * score_padroes ) # 6. Classificação if score_final >= 0.5: classificacao = "DESFAVORÁVEL" emoji = "❌" elif score_final >= 0.3: classificacao = "REVISÃO" emoji = "⚠️" else: classificacao = "FAVORÁVEL" emoji = "✅" return { 'classificacao': classificacao, 'emoji': emoji, 'score_final': score_final, 'sinais': { 'radar': score_radar, 'azmina': score_azmina if azmina else None, 'keywords': score_keywords, 'padroes': score_padroes }, 'pesos': { 'radar': peso_radar, 'azmina': peso_azmina, 'keywords': peso_keywords, 'padroes': peso_padroes }, 'detalhes': { 'keywords_encontradas': kw_desfav, 'padroes_alta_prioridade': matches_alta, 'padroes_normais': matches_normais } } # ======================================== # 4. EXEMPLOS DE USO # ======================================== print("=" * 70) print("🧪 TESTANDO CLASSIFICAÇÃO DE PLs") print("=" * 70) exemplos = [ { 'id': 'PL 106/2023', 'ementa': 'Proíbe o uso de símbolos religiosos em paradas LGBTQIA+', 'esperado': 'DESFAVORÁVEL' }, { 'id': 'PL 5034/2020', 'ementa': 'Equipara terapias de conversão à tortura', 'esperado': 'FAVORÁVEL' }, { 'id': 'PL 906/2024', 'ementa': 'Impede a presença de menores em eventos da comunidade LGBTQIA+', 'esperado': 'DESFAVORÁVEL' }, { 'id': 'PL 1234/2022', 'ementa': 'Dispõe sobre identidade de gênero e nome social em documentos oficiais', 'esperado': 'FAVORÁVEL' } ] for exemplo in exemplos: print(f"\n📄 {exemplo['id']}") print(f" Ementa: \"{exemplo['ementa']}\"") print(f" Esperado: {exemplo['esperado']}") resultado = classificar_pl(exemplo['ementa']) print(f" {resultado['emoji']} Classificação: {resultado['classificacao']}") print(f" 📊 Score Final: {resultado['score_final']:.2%}") print(f" 🔍 Detalhes:") print(f" - Radar Social: {resultado['sinais']['radar']:.2%} (peso {resultado['pesos']['radar']:.0%})") if resultado['sinais']['azmina'] is not None: print(f" - AzMina: {resultado['sinais']['azmina']:.2%} (peso {resultado['pesos']['azmina']:.0%})") print(f" - Keywords: {resultado['sinais']['keywords']:.2%} (peso {resultado['pesos']['keywords']:.0%})") print(f" - Padrões: {resultado['sinais']['padroes']:.2%} (peso {resultado['pesos']['padroes']:.0%})") # Verificar se acertou acertou = "✅" if resultado['classificacao'] == exemplo['esperado'] else "❌" print(f" {acertou} Classificação correta? {resultado['classificacao'] == exemplo['esperado']}") print("\n" + "=" * 70) print("✅ Exemplos concluídos!") print("=" * 70) # ======================================== # 5. USO INTERATIVO # ======================================== print("\n💡 Dica: Para usar interativamente, chame:") print(" resultado = classificar_pl('sua ementa aqui')") print(" print(resultado)")