Implementação Prática de um Sistema de Classificação Automática de Tickets com StructBERT

  1. Introdução: O Papel dos Modelos de Linguagem na Classificação de Textos

Em cenários corporativos, como sistemas de atendimento ao cliente, uma grande variedade de solicitações (consultas, reclamações, sugestões, relatos de falhas) é recebida diariamente. Abordagens tradicionais de classificação textual dependem fortemente de dados rotulados e ciclos de treinamento de modelos, o que pode ser custoso e demorado. A classificação zero-shot surge como uma alternativa revolucionária, utilizando modelos pré-treinados de grande escala para categorizar textos sem necesssidade de exemplos anotados específicos.

O StructBERT, desenvolvido pelo DAMO Academy, é um modelo de linguagem pré-treinado para chinês que demonstra excelente desempenho em tarefas de compreensão semântica. Sua variante para classificação zero-shot, disponível na plataforma ModelScope, permite definir categorias dinamicamente e realizar inferência imediatamente. Este artigo descreve a implementação de um sistema de classificação automática de tickets com uma interface web integrada, detalhando princípios técnicos e boas práticas de engenharia.

  1. Fundamentos Técnicos da Classificação Zero-Shot

2.1 Mecanismo Central

A classificação zero-shot difere da aprendizagem supervisionada tradicional. Seu princípio consiste em utilizar a capacidade semântica de um modelo pré-treinado para mapear tanto o texto de entrada quanto as descrições das categorias candidatas para um mesmo espaço vetorial. A similaridade entre os vetores determina a categoria mais provável.

Por exemplo, dado o texto "Meu pedido ainda não foi enviado" e as categorias ["Consulta", "Reclamação", "Sugestão"], o modelo gera representações semânticas para cada rótulo e as compara com a representação do texto, retornando pontuações de confiança.

Observação crucial: A classificação zero-shot não opera "sem conhecimento"; ela utiliza o conhecimento semântico profundo adquirido durante a pré-treinagem em grandes corpora de texto.

2.2 Vantagens do StructBERT na Compreensão Semântica em Chinês

O StructBERT aprimora a arquitetura BERT padrão ao incorporar tarefas de modelagem estruturada da linguagem, que explicitamente capturam a ordem das palavras e a estrutura frasal. Isso o torna particularmente eficaz para o chinês. Suas características relevantes para zero-shot incluem:

  1. Codificador Semântico Reforçado: Treinamento com tarefas de restauração de sequências embaralhadas.

  2. Contextualização Dinâmica dos Rótulos: O significado das categorias é interpretado considerando o contexto do texto.

  3. Robustez para Rótulos Novos: Capacidade de generalização mesmo para combinações de categorias não vistas durante o treinamento.

  4. Desenvolvimento e Implantação do Sistema


3.1 Preparação do Ambiente

O projeto requer um ambiente com Python e as bibliotecas torch, transformers ou modelscope, e fastapi. A instalação básica pode ser feita via pip:

pip install torch modelscope fastapi uvicorn

3.2 Lógica de Inferência com o Pipeline do ModelScope

A forma mais simples de utilizar o modelo é através do pipeline do ModelScope. O código abaixo inicializa o classificador zero-shot:

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks

# Inicializar o pipeline de classificação de texto
classifier = pipeline(
    task=Tasks.text_classification,
    model='damo/StructBERT-large-zero-shot-classification'
)

3.3 Serviço de API REST com FastAPI

Para expor a funcionalidade, criamos uma API simples. Note como a estrutura e as variáveis foram reorganizadas em relação a um exemplo típico:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List

app = FastAPI(title="Serviço de Classificação Zero-Shot")

class RequisicaoClassificacao(BaseModel):
    texto_para_analisar: str
    categorias_disponiveis: List[str]

@app.post("/analisar_classificacao/")
async def analisar_classificacao(requisicao: RequisicaoClassificacao):
    if not requisicao.texto_para_analisar.strip():
        raise HTTPException(status_code=400, detail="O texto de entrada não pode estar vazio.")
    
    # Executar a inferência
    resultado_inferencia = classifier(
        input=requisicao.texto_para_analisar,
        labels=requisicao.categorias_disponiveis
    )
    
    # Formatar a resposta
    resposta_ordenada = sorted(
        [{"categoria": rotulo["label"], "pontuacao_confianca": round(rotulo["score"], 4)}
         for rotulo in resultado_inferencia["labels"]],
        key=lambda x: x["pontuacao_confianca"],
        reverse=True
    )
    
    return {"classificacoes": resposta_ordenada}

3.4 Interface Web Básica (Exemplo)

Uma interface simples pode ser construída com HTML/JavaScript para enviar requisições à API. O código a seguir demonstra a lógica de submissão:

<form id="formClassificacao">
    <textarea id="campoTexto" placeholder="Insira o texto do ticket..."></textarea>
    <input type="text" id="campoCategorias" placeholder="Ex: Problema técnico, Faturamento, Sugestão"/>
    <button type="button" onclick="enviarParaClassificacao()">Classificar</button>
</form>

<script>
async function enviarParaClassificacao() {
    const texto = document.getElementById('campoTexto').value;
    const categoriasString = document.getElementById('campoCategorias').value;
    const listaCategorias = categoriasString.split(',').map(c => c.trim()).filter(c => c);
    
    const resposta = await fetch('/analisar_classificacao/', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({
            texto_para_analisar: texto,
            categorias_disponiveis: listaCategorias
        })
    });
    
    const dados = await resposta.json();
    // Lógica para exibir os resultados (ex: gráfico ou tabela)
    console.log(dados.classificacoes);
}
</script>

  1. Otimizações e Boas Práticas

4.1 Design de Rótulos Eficiente

A escolha das categorias impacta diretamente a performance. Recomenda-se:

  • Utilizra termos claros e mutuamente exclusivos (ex: "Erro no Pagamento" é melhor que "Problema").
  • Manter uma lista controlada e alinhada com os processos de negócio.

4.2 Avaliação e Validiação

É essencial validar a acurácia com um conjunto de teste representativo. Um script de avaliação pode ser estruturado assim:

conjunto_teste = [
    ("Não consigo acessar minha conta", "Problema de Acesso"),
    ("Gostaria de sugerir um novo recurso", "Sugestão"),
    ("O aplicativo fecha sozinho", "Bug Reportado"),
]

rotulos_validos = ["Problema de Acesso", "Sugestão", "Bug Reportado", "Consulta Geral"]
acertos = 0

for texto, esperado in conjunto_teste:
    predicao = classifier(input=texto, labels=rotulos_validos)
    rotulo_predito = predicao["labels"][0]["label"]
    if rotulo_predito == esperado:
        acertos += 1

acuracia = acertos / len(conjunto_teste)
print(f"Acurácia no conjunto de teste: {acuracia:.2%}")

4.3 Tratamento de Incerteza

Definir um limiar de confiança (ex: 0.65) ajuda a identificar casos ambíguos que requerem revisão humana:

melhor_categoria = resposta_ordenada[0]
if melhor_categoria["pontuacao_confianca"] < 0.65:
    rotulo_final = "Requer Revisão Manual"
else:
    rotulo_final = melhor_categoria["categoria"]

  1. Extensões e Casos de Uso

A técnica de classificação zero-shot é versátil e pode ser aplicada em diversos domínios:

Cenário Exempols de Categorias Benefício Principal
Análise de Sentimento em Mídias Sociais Positivo, Neutro, Negativo, Irônico Monitoramento de marca em tempo real
Triagem de E-mails Corporativos Urgente, Para Ação, Informativo, SPAM Priorização automática da caixa de entrada
Categorização de Documentos Legais Contrato, NDA, Fatura, Reclamação Formal Organização eficiente do acervo digital

A integração com sistemas existentes pode ser feita via consumo da API REST (/analisar\_classificacao/), permitindo a incorporação em fluxos de trabalho automatizados, como roteamento de tickets em plataformas de helpdesk.

Tags: StructBERT zero-shot classification FastAPI nlp Text Classification

Publicado em 7-13 07:00