🏳️🌈 Radar Social LGBTQIA+ V2
Análise Completa da Base de 12.102 Registros
Modelo RLHF Final | Análise Detalhada | Relatório Completo
#!/usr/bin/env python3 """ Radar Social LGBTQIA+ V2 - Análise Completa da Base Space para análise completa dos 12.102 registros com o modelo RLHF final """ import gradio as gr import pandas as pd import torch from transformers import AutoTokenizer, AutoModelForSequenceClassification from pathlib import Path import logging from datetime import datetime from tqdm import tqdm import os # Configurar logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Versão: 1.2 - Build forçado com correções # Data: 2025-10-25 15:50 class RadarSocialV2: def __init__(self): self.model = None self.tokenizer = None self.dataset = None self.predictions = None self.load_model() self.load_dataset() def load_model(self): """Carrega o modelo RLHF final.""" try: logger.info("📥 Carregando modelo RLHF final...") # Usar modelo do Hugging Face Hub model_name = "Veronyka/tupi-bert-lgbtqia-trained" self.tokenizer = AutoTokenizer.from_pretrained(model_name) self.model = AutoModelForSequenceClassification.from_pretrained( model_name, num_labels=2, torch_dtype=torch.float32 ) logger.info(f"✅ Modelo carregado do Hub: {model_name}") self.model = self.model.to('cpu') self.model.eval() logger.info("🖥️ Modelo pronto para inferência") except Exception as e: logger.error(f"❌ Erro ao carregar modelo: {e}") raise def load_dataset(self): """Carrega a base de dados completa.""" try: logger.info("📊 Carregando base de dados completa...") # Tentar múltiplos caminhos possíveis possible_paths = [ Path("dataset_three_platforms_clean_20251020_140406.csv"), Path("data/dataset_three_platforms_clean_20251020_140406.csv"), Path("/home/user/app/dataset_three_platforms_clean_20251020_140406.csv"), Path("/home/user/app/data/dataset_three_platforms_clean_20251020_140406.csv") ] data_path = None for path in possible_paths: logger.info(f"🔍 Procurando em: {path}") if path.exists(): data_path = path logger.info(f"✅ Arquivo encontrado em: {path}") break if data_path is None: # Listar arquivos disponíveis para debug logger.error("❌ Arquivo não encontrado em nenhum local!") logger.error("📁 Arquivos disponíveis:") for root, dirs, files in os.walk("."): for file in files: logger.error(f" {os.path.join(root, file)}") raise FileNotFoundError("Base de dados não encontrada!") self.dataset = pd.read_csv(data_path) logger.info(f"✅ Base carregada: {len(self.dataset)} exemplos") except Exception as e: logger.error(f"❌ Erro ao carregar base: {e}") raise def predict_text(self, text): """Prediz hate speech para um texto.""" try: # Tokenizar inputs = self.tokenizer( text, truncation=True, padding=True, max_length=512, return_tensors='pt' ) # Predizer with torch.no_grad(): outputs = self.model(**inputs) probs = torch.softmax(outputs.logits, dim=-1) pred = torch.argmax(probs, dim=-1).item() confidence = probs.max().item() # Resultado label = "HATE" if pred == 1 else "NÃO-HATE" prob_hate = probs[0][1].item() return label, confidence, prob_hate except Exception as e: logger.error(f"❌ Erro na predição: {e}") return "ERRO", 0.0, 0.0 def analyze_complete_dataset(self): """Analisa a base completa de 12.102 registros.""" try: logger.info("🔍 Iniciando análise completa da base...") results = [] hate_count = 0 total_confidence = 0 # Processar todos os registros for idx, row in tqdm(self.dataset.iterrows(), total=len(self.dataset), desc="Analisando"): text = row['text'] platform = row['platform'] label, confidence, prob_hate = self.predict_text(text) if label == "HATE": hate_count += 1 total_confidence += confidence results.append({ 'id': row['id'], 'text': text, 'platform': platform, 'prediction': label, 'confidence': confidence, 'prob_hate': prob_hate }) # Calcular estatísticas total_examples = len(results) hate_percentage = (hate_count / total_examples) * 100 avg_confidence = total_confidence / total_examples # Salvar resultados self.predictions = pd.DataFrame(results) # Gerar relatório completo report = f""" # 🏳️🌈 ANÁLISE COMPLETA DA BASE - RADAR SOCIAL LGBTQIA+ V2 ## 📊 RESUMO GERAL - **Total de exemplos analisados**: {total_examples:,} - **HATE detectado**: {hate_count:,} ({hate_percentage:.1f}%) - **NÃO-HATE detectado**: {total_examples - hate_count:,} ({100-hate_percentage:.1f}%) - **Confiança média**: {avg_confidence:.1%} ## 📱 ANÁLISE POR PLATAFORMA """ # Estatísticas por plataforma platform_stats = self.predictions.groupby('platform').agg({ 'prediction': ['count', lambda x: (x == 'HATE').sum()], 'confidence': 'mean' }).round(3) platform_stats.columns = ['Total', 'Hate_Count', 'Avg_Confidence'] platform_stats['Hate_Percentage'] = (platform_stats['Hate_Count'] / platform_stats['Total'] * 100).round(1) for platform in platform_stats.index: stats = platform_stats.loc[platform] report += f""" ### {platform} - **Total**: {stats['Total']:,} exemplos - **HATE**: {stats['Hate_Count']:,} ({stats['Hate_Percentage']:.1f}%) - **Confiança média**: {stats['Avg_Confidence']:.1%} """ # Exemplos de alta confiança high_conf_hate = self.predictions[ (self.predictions['prediction'] == 'HATE') & (self.predictions['confidence'] > 0.95) ].head(10) high_conf_no_hate = self.predictions[ (self.predictions['prediction'] == 'NÃO-HATE') & (self.predictions['confidence'] > 0.95) ].head(10) report += f""" ## 🔥 EXEMPLOS DE HATE (Alta Confiança > 95%) """ for idx, row in high_conf_hate.iterrows(): report += f"- **{row['platform']}** ({row['confidence']:.1%}): {row['text'][:100]}...\n" report += f""" ## ✅ EXEMPLOS DE NÃO-HATE (Alta Confiança > 95%) """ for idx, row in high_conf_no_hate.iterrows(): report += f"- **{row['platform']}** ({row['confidence']:.1%}): {row['text'][:100]}...\n" # Distribuição de confiança conf_ranges = [ (0.9, 1.0, "Muito Alta (90-100%)"), (0.8, 0.9, "Alta (80-90%)"), (0.7, 0.8, "Média (70-80%)"), (0.6, 0.7, "Baixa (60-70%)"), (0.0, 0.6, "Muito Baixa (<60%)") ] report += f""" ## 📈 DISTRIBUIÇÃO DE CONFIANÇA """ for min_conf, max_conf, label in conf_ranges: count = len(self.predictions[ (self.predictions['confidence'] >= min_conf) & (self.predictions['confidence'] < max_conf) ]) percentage = (count / total_examples) * 100 report += f"- **{label}**: {count:,} exemplos ({percentage:.1f}%)\n" report += f""" ## 🎯 CONCLUSÕES - O modelo RLHF final apresenta **{avg_confidence:.1%}** de confiança média - **{hate_percentage:.1f}%** dos conteúdos foram classificados como hate speech - A distribuição varia por plataforma, indicando diferentes padrões de linguagem - O modelo está pronto para uso em produção com alta confiabilidade --- *Análise realizada em {datetime.now().strftime('%d/%m/%Y %H:%M')}* """ return report except Exception as e: logger.error(f"❌ Erro na análise completa: {e}") return f"❌ Erro na análise: {e}" # Inicializar o radar radar = RadarSocialV2() # Interface Gradio def create_interface(): with gr.Blocks( title="Radar Social LGBTQIA+ V2 - Análise Completa", theme=gr.themes.Soft(), css=""" .gradio-container { max-width: 1400px !important; } .main-header { text-align: center; padding: 20px; background: linear-gradient(90deg, #ff6b6b, #4ecdc4); color: white; border-radius: 10px; margin-bottom: 20px; } .warning-box { background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 8px; padding: 15px; margin: 20px 0; } """ ) as demo: gr.HTML("""
Análise Completa da Base de 12.102 Registros
Modelo RLHF Final | Análise Detalhada | Relatório Completo
Esta análise processará todos os 12.102 registros da base completa. O processo pode levar alguns minutos para ser concluído.
O resultado será um relatório detalhado com estatísticas por plataforma, exemplos de alta confiança e distribuição de confiança do modelo.
🏳️🌈 Radar Social LGBTQIA+ V2 | Análise Completa da Base
Desenvolvido com ❤️ para a comunidade LGBTQIA+ brasileira
Última atualização: """ + datetime.now().strftime("%d/%m/%Y %H:%M") + """