Hot News
Esta nova série de artigos foca em trabalhar com LLMs para escalar suas tarefas de SEO. Esperamos ajudar você a integrar IA em SEO para que você possa aprimorar suas habilidades.
Esperamos que você tenha gostado do artigo anterior e tenha entendido o que são vetores, distância vetorial e incorporações de texto.
Depois disso, é hora de exercitar seus “músculos do conhecimento de IA” aprendendo a usar incorporações de texto para encontrar canibalização de palavras-chave.
Começaremos com os embeddings de texto do OpenAI e os compararemos.
Modelo | Dimensionalidade | Preços | Notas |
---|---|---|---|
incorporação-de-texto-ada-002 | 1536 | US$ 0,10 por 1 milhão de tokens | Ótimo para a maioria dos casos de uso. |
texto-incorporado-3-pequeno | 1536 | $ 0,002 por 1 milhão de tokens | Mais rápido e barato, mas menos preciso |
texto-incorporado-3-grande | 3072 | US$ 0,13 por 1 milhão de tokens | Mais preciso para tarefas complexas relacionadas a textos longos, mais lento |
(*tokens podem ser considerados palavras.)
Mas antes de começar, você precisa instalar o Python e o Jupyter no seu computador.
Jupyter é uma ferramenta baseada na web para profissionais e pesquisadores. Ela permite que você execute análises complexas de dados e desenvolvimento de modelos de machine learning usando qualquer linguagem de programação.
Não se preocupe – é muito fácil e leva pouco tempo para terminar as instalações. E lembre-se, o ChatGPT é seu amigo quando se trata de programação.
Em poucas palavras:
- Baixe e instale o Python.
- Abra a linha de comando do Windows ou o terminal no Mac.
- Digite estes comandos
pip install jupyterlab
epip install notebook
- Execute o Jupiter com este comando:
jupyter lab
Usaremos o Jupyter para experimentar incorporações de texto; você verá como é divertido trabalhar com ele!
Mas antes de começar, você deve se inscrever na API da OpenAI e configurar o faturamento preenchendo seu saldo.
![Configurações de faturamento da API Open AI](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/open-ai-api-644.png?resize=640%2C294&ssl=1)
Depois de fazer isso, configure notificações por e-mail para informá-lo quando seus gastos excederem um determinado valor. Limites de uso.
Em seguida, obtenha as chaves da API em Painel > Chaves de API, que você deve manter em sigilo e nunca compartilhar publicamente.
![Chaves de API OpenAI](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/openai-api-keys-638.png?resize=640%2C290&ssl=1)
Agora, você tem todas as ferramentas necessárias para começar a brincar com embeddings.
- Abra o terminal de comando do seu computador e digite
jupyter lab
. - Você deverá ver algo parecido com a imagem abaixo aparecer no seu navegador.
- Clique em Python 3 sob Caderno.
![laboratório jupyter](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/jupyter-448.png?resize=610%2C276&ssl=1)
Na janela aberta, você escreverá seu código.
Como uma pequena tarefa, vamos agrupar URLs semelhantes de um CSV. O CSV de exemplo tem duas colunas: URL e Título. A tarefa do nosso script será agrupar URLs com significados semânticos semelhantes com base no título para que possamos consolidar essas páginas em uma e corrigir problemas de canibalização de palavras-chave.
Aqui estão os passos que você precisa seguir:
Instale as bibliotecas Python necessárias com os seguintes comandos no terminal do seu PC (ou no notebook Jupyter)
pip install pandas openai scikit-learn numpy unidecode
A biblioteca ‘openai’ é necessária para interagir com a API OpenAI para obter incorporações, e ‘pandas’ é usada para manipulação de dados e tratamento de operações de arquivos CSV.
A biblioteca ‘scikit-learn’ é necessária para calcular similaridade de cosseno, e ‘numpy’ é essencial para operações numéricas e manipulação de arrays. Por fim, unidecode é usado para limpar texto.
Em seguida, baixe a planilha de amostra como um CSV, renomeie o arquivo para pages.csv e carregue-o na pasta Jupyter onde seu script está localizado.
Defina sua chave de API OpenAI como a chave obtida na etapa acima e copie e cole o código abaixo no notebook.
Execute o código clicando no ícone de triângulo de reprodução na parte superior do notebook.
import pandas as pd
import openai
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
import csv
from unidecode import unidecode
# Function to clean text
def clean_text(text: str) -> str:
# First, replace known problematic characters with their correct equivalents
replacements = {
'–': '–', # en dash
'’': '’', # right single quotation mark
'“': '“', # left double quotation mark
'â€': '”', # right double quotation mark
'‘': '‘', # left single quotation mark
'â€': '—' # em dash
}
for old, new in replacements.items():
text = text.replace(old, new)
# Then, use unidecode to transliterate any remaining problematic Unicode characters
text = unidecode(text)
return text
# Load the CSV file with UTF-8 encoding from root folder of Jupiter project folder
df = pd.read_csv('pages.csv', encoding='utf-8')
# Clean the 'Title' column to remove unwanted symbols
df['Title'] = df['Title'].apply(clean_text)
# Set your OpenAI API key
openai.api_key = 'your-api-key-goes-here'
# Function to get embeddings
def get_embedding(text):
response = openai.Embedding.create(input=[text], engine="text-embedding-ada-002")
return response['data'][0]['embedding']
# Generate embeddings for all titles
df['embedding'] = df['Title'].apply(get_embedding)
# Create a matrix of embeddings
embedding_matrix = np.vstack(df['embedding'].values)
# Compute cosine similarity matrix
similarity_matrix = cosine_similarity(embedding_matrix)
# Define similarity threshold
similarity_threshold = 0.9 # since threshold is 0.1 for dissimilarity
# Create a list to store groups
groups = []
# Keep track of visited indices
visited = set()
# Group similar titles based on the similarity matrix
for i in range(len(similarity_matrix)):
if i not in visited:
# Find all similar titles
similar_indices = np.where(similarity_matrix[i] >= similarity_threshold)[0]
# Log comparisons
print(f"\nChecking similarity for '{df.iloc[i]['Title']}' (Index {i}):")
print("-" * 50)
for j in range(len(similarity_matrix)):
if i != j: # Ensure that a title is not compared with itself
similarity_value = similarity_matrix[i, j]
comparison_result="greater" if similarity_value >= similarity_threshold else 'less'
print(f"Compared with '{df.iloc[j]['Title']}' (Index {j}): similarity = {similarity_value:.4f} ({comparison_result} than threshold)")
# Add these indices to visited
visited.update(similar_indices)
# Add the group to the list
group = df.iloc[similar_indices][['URL', 'Title']].to_dict('records')
groups.append(group)
print(f"\nFormed Group {len(groups)}:")
for item in group:
print(f" - URL: {item['URL']}, Title: {item['Title']}")
# Check if groups were created
if not groups:
print("No groups were created.")
# Define the output CSV file
output_file="grouped_pages.csv"
# Write the results to the CSV file with UTF-8 encoding
with open(output_file, 'w', newline="", encoding='utf-8') as csvfile:
fieldnames = ['Group', 'URL', 'Title']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for group_index, group in enumerate(groups, start=1):
for page in group:
cleaned_title = clean_text(page['Title']) # Ensure no unwanted symbols in the output
writer.writerow({'Group': group_index, 'URL': page['URL'], 'Title': cleaned_title})
print(f"Writing Group {group_index}, URL: {page['URL']}, Title: {cleaned_title}")
print(f"Output written to {output_file}")
Este código lê um arquivo CSV, ‘pages.csv’, contendo títulos e URLs, que você pode exportar facilmente do seu CMS ou obter rastreando um site de cliente usando o Screaming Frog.
Em seguida, ele limpa os títulos de caracteres não UTF, gera vetores de incorporação para cada título usando a API do OpenAI, calcula a similaridade entre os títulos, agrupa títulos semelhantes e grava os resultados agrupados em um novo arquivo CSV, ‘grouped_pages.csv’.
Na tarefa de canibalização de palavras-chave, usamos um limite de similaridade de 0,9, o que significa que se a similaridade do cosseno for menor que 0,9, consideraremos os artigos como diferentes. Para visualizar isso em um espaço bidimensional simplificado, ele aparecerá como dois vetores com um ângulo de aproximadamente 25 graus entre eles.
No seu caso, você pode querer usar um limite diferente, como 0,85 (aproximadamente 31 graus entre eles), e executá-lo em uma amostra dos seus dados para avaliar os resultados e a qualidade geral das correspondências. Se for insatisfatório, você pode aumentar o limite para torná-lo mais rigoroso para melhor precisão.
Você pode instalar o ‘matplotlib’ via terminal.
E use o código Python abaixo em um notebook Jupyter separado para visualizar similaridades de cosseno em espaço bidimensional por conta própria. Experimente; é divertido!
import matplotlib.pyplot as plt
import numpy as np
# Define the angle for cosine similarity of 0.9. Change here to your desired value.
theta = np.arccos(0.9)
# Define the vectors
u = np.array([1, 0])
v = np.array([np.cos(theta), np.sin(theta)])
# Define the 45 degree rotation matrix
rotation_matrix = np.array([
[np.cos(np.pi/4), -np.sin(np.pi/4)],
[np.sin(np.pi/4), np.cos(np.pi/4)]
])
# Apply the rotation to both vectors
u_rotated = np.dot(rotation_matrix, u)
v_rotated = np.dot(rotation_matrix, v)
# Plotting the vectors
plt.figure()
plt.quiver(0, 0, u_rotated[0], u_rotated[1], angles="xy", scale_units="xy", scale=1, color="r")
plt.quiver(0, 0, v_rotated[0], v_rotated[1], angles="xy", scale_units="xy", scale=1, color="b")
# Setting the plot limits to only positive ranges
plt.xlim(0, 1.5)
plt.ylim(0, 1.5)
# Adding labels and grid
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True)
plt.title('Visualization of Vectors with Cosine Similarity of 0.9')
# Show the plot
plt.show()
Geralmente uso 0,9 e superior para identificar problemas de canibalização de palavras-chave, mas pode ser necessário defini-lo como 0,5 ao lidar com redirecionamentos de artigos antigos, pois artigos antigos podem não ter artigos quase idênticos que sejam mais recentes, mas parcialmente próximos.
Também pode ser melhor ter a meta description concatenada com o título em caso de redirecionamentos, além do título.
Então, depende da tarefa que você está realizando. Revisaremos como implementar redirecionamentos em um artigo separado mais adiante nesta série.
Agora, vamos revisar os resultados com os três modelos mencionados acima e ver como eles foram capazes de identificar artigos próximos da nossa amostra de dados dos artigos do Search Engine Journal.
![Amostra de dados](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/sample-718.png?resize=640%2C149&ssl=1)
Da lista, já vemos que o 2º e o 4º artigos cobrem o mesmo tópico sobre ‘meta tags’. Os artigos nas 5ª e 7ª linhas são praticamente os mesmos – discutindo a importância das tags H1 em SEO – e podem ser mesclados.
O artigo na 3ª linha não tem semelhanças com nenhum dos artigos da lista, mas tem palavras comuns como “Tag” ou “SEO”.
O artigo na 6ª linha é novamente sobre H1, mas não exatamente o mesmo que a importância de H1 para SEO. Em vez disso, ele representa a opinião do Google sobre se eles devem corresponder.
Os artigos na 8ª e 9ª linhas são bem próximos, mas ainda assim diferentes; eles podem ser combinados.
incorporação-de-texto-ada-002
Ao usar ‘text-embedding-ada-002’, encontramos precisamente o 2º e o 4º artigos com uma similaridade de cosseno de 0,92 e o 5º e o 7º artigos com uma similaridade de 0,91.
![Captura de tela do log do Jupyter mostrando semelhanças de cosseno](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/log-similairty-909.png?resize=640%2C427&ssl=1)
E gerou uma saída com URLs agrupadas usando o mesmo número de grupo para artigos semelhantes. (as cores são aplicadas manualmente para fins de visualização).
![Folha de saída com URLs agrupadas](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/cosine-similairty-502.png?resize=640%2C142&ssl=1)
Para o 2º e 3º artigos, que têm palavras comuns “Tag” e “SEO”, mas não são relacionadas, a similaridade do cosseno foi de 0,86. Isso mostra por que um alto limite de similaridade de 0,9 ou maior é necessário. Se o definirmos como 0,85, ele estaria cheio de falsos positivos e poderia sugerir a fusão de artigos não relacionados.
texto-incorporado-3-pequeno
Ao usar ‘text-embedding-3-small’, surpreendentemente, ele não encontrou nenhuma correspondência dentro do nosso limite de similaridade de 0,9 ou superior.
Para o 2º e 4º artigos, a similaridade do cosseno foi de 0,76, e para o 5º e 7º artigos, com similaridade de 0,77.
Para entender melhor esse modelo por meio de experimentação, adicionei uma versão ligeiramente modificada da 1ª linha com ’15’ vs. ’14’ à amostra.
- “14 Meta e HTML Tags Mais Importantes que Você Precisa Saber para SEO”
- “15 Meta e HTML Tags Mais Importantes que Você Precisa Saber para SEO”
![Exemplo que mostra resultados de text-embedding-3-small](https://i0.wp.com/www.searchenginejournal.com/wp-content/uploads/2024/06/text-embedding-3-small-example-682.png?resize=640%2C114&ssl=1)
Pelo contrário, ‘text-embedding-ada-002’ deu 0,98 de similaridade de cosseno entre essas versões.
Título 1 | Título 2 | Similaridade de cosseno |
14 Meta e tags HTML mais importantes que você precisa saber para SEO | 15 Meta e tags HTML mais importantes que você precisa saber para SEO | 0,92 |
14 Meta e tags HTML mais importantes que você precisa saber para SEO | Meta Tags: O que você precisa saber para SEO | 0,76 |
Aqui, vemos que esse modelo não é muito adequado para comparar títulos.
texto-incorporado-3-grande
A dimensionalidade deste modelo é 3072, que é 2 vezes maior que a de ‘text-embedding-3-small’ e ‘text-embedding-ada-002’, com dimensionalidade 1536.
Como ele tem mais dimensões que os outros modelos, poderíamos esperar que ele capturasse o significado semântico com maior precisão.
Entretanto, ele deu ao 2º e 4º artigos uma similaridade de cosseno de 0,70 e ao 5º e 7º artigos uma similaridade de 0,75.
Testei novamente com versões ligeiramente modificadas do primeiro artigo com ’15’ em vez de ’14’ e sem ‘Mais Importante’ no título.
- “14 Meta e HTML Tags Mais Importantes que Você Precisa Saber para SEO”
- “15 Meta e HTML Tags Mais Importantes que Você Precisa Saber para SEO”
- “14 Meta e tags HTML que você precisa saber para SEO”
Título 1 | Título 2 | Similaridade de cosseno |
14 Meta e tags HTML mais importantes que você precisa saber para SEO | 15 Meta e tags HTML mais importantes que você precisa saber para SEO | 0,95 |
14 Meta e tags HTML mais importantes que você precisa saber para SEO | 14 |
0,93 |
14 Meta e tags HTML mais importantes que você precisa saber para SEO | Meta Tags: O que você precisa saber para SEO | 0,70 |
15 Meta e tags HTML mais importantes que você precisa saber para SEO | 14 |
0,86 |
Então podemos ver que ‘text-embedding-3-large’ tem desempenho inferior ao ‘text-embedding-ada-002’ quando calculamos similaridades de cosseno entre títulos.
Quero ressaltar que a precisão de ‘text-embedding-3-large’ aumenta com o comprimento do texto, mas ‘text-embedding-ada-002’ ainda tem melhor desempenho geral.
Outra abordagem poderia ser remover stop words do texto. Removê-las pode, às vezes, ajudar a focar os embeddings em palavras mais significativas, melhorando potencialmente a precisão de tarefas como cálculos de similaridade.
A melhor maneira de determinar se a remoção de palavras irrelevantes melhora a precisão da sua tarefa e conjunto de dados específicos é testar empiricamente ambas as abordagens e comparar os resultados.
Conclusão
Com esses exemplos, você aprendeu a trabalhar com os modelos de incorporação do OpenAI e já consegue executar uma ampla gama de tarefas.
Para limites de similaridade, você precisa experimentar com seus próprios conjuntos de dados e ver quais limites fazem sentido para sua tarefa específica, executando-a em amostras menores de dados e realizando uma revisão humana da saída.
Observe que o código que temos neste artigo não é ideal para grandes conjuntos de dados, pois você precisa criar incorporações de texto de artigos toda vez que houver uma alteração no seu conjunto de dados para avaliar em relação a outras linhas.
Para torná-lo eficiente, precisamos usar bancos de dados vetoriais e armazenar informações de incorporação lá uma vez geradas. Abordaremos como usar bancos de dados vetoriais muito em breve e alteraremos o exemplo de código aqui para usar um banco de dados vetorial.
Mais recursos:
Imagem em destaque: BestForBest/Shutterstock
Siga-nos nas redes sociais:
Hotnews.pt |
Facebook |
Instagram |
Telegram
#hotnews #noticias #AtualizaçõesDiárias #SigaHotnews #FiquePorDentro #ÚltimasNotícias #InformaçãoAtual