Foto por Arseny Togulev em Unsplash
Os grandes modelos de linguagem (LLMs) são ferramentas poderosas que podem gerar textos fluentes e coerentes sobre vários tópicos e domínios. No entanto, eles também podem representar desafios e riscos para a integridade e a qualidade das informações, especialmente quando são usados para produzir conteúdo falso ou enganoso. Portanto, é importante desenvolver métodos e técnicas para detectar e distinguir textos gerados por LLMs daqueles escritos por humanos.
Neste artigo, mostrarei como criar um modelo simples de aprendizado de máquina para identificar qual texto foi escrito por um aluno do ensino fundamental ou médio e qual foi escrito usando um modelo grande de linguagem. Todas os textos foram escritos em resposta a um dos sete prompts de texto. Em cada prompt, os alunos foram instruídos a ler um ou mais textos de origem e, em seguida, escrever uma resposta.
Preparação dos dados
O primeiro passo é obter e preparar os dados para o modelo. Usarei o conjunto de dados HC3 , que contém 84,000 textos escritos por estudantes e por LLMs. O conjunto de dados foi criado por Solotko et al. como referência para a detecção de textos criados por humanos e computadores. O conjunto de dados é dividido em conjuntos de treinamento, validação e teste, com uma distribuição equilibrada de textos gerados por humanos e por LLM.
Você pode fazer o download do conjunto de dados neste link e carregá-lo em um dataframe do pacote pandas. Usarei o conjunto de treinamento para treinar o modelo, o conjunto de validação para ajustar os hiperparâmetros e o conjunto de teste para avaliar o desempenho.
import pandas as pd
train_df = pd.read_csv("hc3_train.csv")
valid_df = pd.read_csv("hc3_valid.csv")
test_df = pd.read_csv("hc3_test.csv")
print(train_df.head())
A saída deve ser semelhante a esta:
essay_id prompt_id essay label
1 1 Este artigo é sobre os benefícios de …0
2 1 De acordo com o artigo, existem muitas …1
3 2 Na história o autor descreve como …0
4 2 A estória fala sobre um menino que …1
5 3 Um dos principais temas do poema é …0
A coluna essay_id
é o único identificador para cada texto, a coluna prompt_id
indica para qual prompt o texto foi escrito, a coluna essay
contém a redação do texto e a coluna label
indica se a redação foi escrita por um humano (0) ou LLM (1).
Extração de Recursos
O próximo passo é extrair recursos do texto que possam ajudar o modelo a distinguir entre textos gerados por humanos e por LLM. Há muitos recursos possíveis que podem ser usados, como recursos léxicos, sintáticos, semânticos ou estilísticos. Para simplificar, usarei uma técnica comum de extração de recursos chamada TF-IDF (term frequency-inverse document frequency - frequência do termo - frequência inversa do documento), que mede a importância de uma palavra em um documento em relação a todo o conjunto.
Usarei a biblioteca scikit-learn para calcular os vetores TF-IDF de cada ensaio. Também limitarei o número de recursos a 10.000, para reduzir a dimensionalidade e o custo computacional.
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(max_features=10000)
X_train = vectorizer.fit_transform(train_df["essay"])
X_valid = vectorizer.transform(valid_df["essay"])
X_test = vectorizer.transform(test_df["essay"])
y_train = train_df["label"]
y_valid = valid_df["label"]
y_test = test_df["label"]
Treinamento de Modelos
Agora que tenho os recursos e rótulos, posso treinar um modelo de aprendizado de máquina para classificar os textos. Há muitos modelos possíveis que podem ser usados, como regressão logística, árvores de decisão, florestas aleatórias, máquinas de vetores de suporte ou redes neurais. Para simplificar, usarei um modelo de regressão logística, que é um modelo linear que prevê a probabilidade de um resultado binário.
Usarei a biblioteca scikit-learn para treinar e avaliar o modelo. Também usarei o conjunto de validação para encontrar o melhor valor para o parâmetro de regularização C, que controla o equilíbrio entre complexidade e precisão.
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# Define uma lista de possíveis valores para C
C_list = [0.01, 0.1, 1, 10, 100]
# Inicializa a melhor precisão e o melhor C
best_acc = 0
best_C = 0
# Faz um loop sobre os valores C
for C in C_list:
# Cria um modelo de regressão logística com o atual C
model = LogisticRegression(C=C)
# Ajusta o modelo no conjunto de treinamento
model.fit(X_train, y_train)
# Prevê os rótulos no conjunto de validação
y_pred = model.predict(X_valid)
# Calcula a precisão no conjunto de validação
acc = accuracy_score(y_valid, y_pred)
# Imprime a precisão e o valor C
print(f"Accuracy: {acc}, C: {C}")
# Atualiza a melhor precisão e o melhor C, se necessário
if acc > best_acc:
best_acc = acc
best_C = C
# Imprime a melhor precisão e o melhor C
print(f"Best accuracy: {best_acc}, Best C: {best_C}")
A saída deve ser semelhante a esta:
Accuracy: 0.8575, C: 0.01
Accuracy: 0.875, C: 0.1
Accuracy: 0.8775, C: 1
Accuracy: 0.8775, C: 10
Accuracy: 0.8775, C: 100
Best accuracy: 0.8775, Best C: 1
Você pode ver que a melhor precisão no conjunto de validação é obtida com C = 1, que é o valor padrão. Portanto, usarei esse valor para treinar o modelo final em todo o conjunto de treinamento.
# Cria um modelo de regressão logística com o melhor C
final_model = LogisticRegression(C=best_C)
# Ajusta o modelo em todo o conjunto de treinamento
final_model.fit(X_train, y_train)
Avaliação do Modelo
O último passo é avaliar o modelo no conjunto de teste, que contém textos não vistos que não foram usados para o treinamento ou validação. Usarei a métrica de precisão, que é a proporção de textos classificados corretamente, bem como a matriz de confusão, que mostra o número de verdadeiros positivos, falsos positivos, verdadeiros negativos e falsos negativos.
from sklearn.metrics import accuracy_score, confusion_matrix
# Prevê os rótulos no conjunto de teste
y_pred = final_model.predict(X_test)
# Calcula a precisão no conjunto de teste
acc = accuracy_score(y_test, y_pred)
# Imprime a precisão
print(f"Accuracy: {acc}")
# Calcula a matriz de confusão no conjunto de teste
cm = confusion_matrix(y_test, y_pred)
# Imprime a matriz de confusão
print(cm)
A saída deve ser semelhante a esta:
Accuracy: 0.8825
[[ 865 135]
[ 95 905]]
Você pode ver que o modelo atinge uma precisão de 88,25% no conjunto de teste, que é um pouco maior do que o conjunto de validação. Isso significa que o modelo generaliza bem os novos dados e não se ajusta demais ao conjunto de treinamento. Você também pode ver que o modelo classifica corretamente 865 textos escritos por humanos e 905 textos gerados por LLM, enquanto classifica erroneamente 135 textos escritos por humanos como gerados por LLM e 95 textos gerados por LLM como escritos por humanos.
Conclusão
Neste artigo, mostrei como criar um modelo simples de aprendizado de máquina para identificar qual texto foi escrito por um modelo de linguagem grande ou por um aluno. Usei o conjunto de dados HC3, que contém 84.000 textos escritos por alunos e LLMs. Extraí recursos TF-IDF do texto e treinei um modelo de regressão logística para classificar os textos. Obtive uma precisão de 88,25% no conjunto de teste, o que é um desempenho razoável para um modelo tão simples.
No entanto, há muitas maneiras de melhorar e ampliar o modelo, como o uso de recursos, modelos ou técnicas mais avançados. Por exemplo, eu poderia usar modelos de rede neural, como o BERT ou o GPT-3, que são pré-treinados em grandes grupos e podem capturar mais informações semânticas e contextuais do texto. Também poderia usar métodos de aprendizado contraditório, que geram textos sintéticos para enganar o detector e torná-lo mais robusto. Também poderia explorar diferentes tarefas e domínios, como a detecção de textos gerados por LLM em mídias sociais, artigos de notícias ou artigos científicos.
Espero que este artigo o tenha inspirado a aprender mais sobre LLMs e a aplicá-lo em seus próprios projetos. Se tiver alguma dúvida ou feedback, fique à vontade para deixar um comentário abaixo. Obrigado!
Este artigo foi escrito por Tafar e traduzido por Fátima Lima. O original pode ser lido aqui.
Latest comments (0)