Estatística

Tráfego de Bot em Teste A/B: limpar antes de ler

Tráfego de bot em teste A/B só invalida o resultado quando cai desigual entre as variações. Como separar ruído de viés, detectar e filtrar.

Ilustração plana de uma peneira cônica de malha fina cheia de peças angulares idênticas retidas em cima, com poucas peças arredondadas caindo por baixo e formando uma pilha limpa, em tons de verde profundo

Tráfego de bot não invalida um teste A/B por existir, invalida quando cai desigual entre as variações. Robô distribuído de forma não enviesada só adiciona ruído e reduz o poder do experimento; robô que age como um usuário só e alimenta sempre a mesma variação desloca a métrica daquele braço e troca o vencedor. Este guia mostra a diferença entre ruído e viés, por que executar JavaScript não separa pessoa de robô, um exemplo trabalhado em que um crawler apagou um ganho real de 13 por cento, e o método de detecção que os autores do tema propõem. Faz parte do nosso guia completo de teste A/B e é o vizinho direto do viés de instrumentação: lá o instrumento mede errado, aqui quem está sendo medido não é gente.

Ruído e viés são problemas diferentes

A intuição comum é que bot é sujeira e sujeira estraga tudo. A literatura de experimentação é mais precisa que isso.

Crook, Frasca, Kohavi e Longbotham, no artigo de KDD 2009 que catalogou sete armadilhas de experimentos controlados na web, colocam a distinção assim: para experimentação, a preocupação primária é remover os robôs que causam viés. Se o tráfego de um robô se distribui entre as variações de forma não enviesada, a presença dele adiciona ruído ao dado e reduz o poder do experimento, mas não invalida os resultados. Robôs vistos como múltiplos usuários únicos, porque resetam cookies ou rodam de várias máquinas, não introduzem viés. O caso que introduz viés é o robô que age como um único usuário e gera tráfego de forma consistente para uma única variação.

Bot simétrico adiciona ruído, bot assimétrico adiciona viésDois painéis lado a lado. No painel da esquerda, rotulado bot simétrico, dois pares de barras iguais representam as variações A e B com a mesma quantidade de tráfego automatizado somada aos dois lados: a diferença entre os topos das barras humanas permanece a mesma, e a legenda diz que o efeito é ruído e perda de poder. No painel da direita, rotulado bot assimétrico, todo o tráfego automatizado cai apenas sobre a variação B: a barra de B cresce em volume sem crescer em conversão, a diferença entre os topos muda de tamanho e chega a inverter de sinal, e a legenda diz que o efeito é viés e troca de vencedor.A pergunta não é quanto bot existe, é se ele caiu igual dos dois ladosbot simétrico: cai nos dois braçosbot assimétrico: cai só em BABdiferençapreservadaverde claro = tráfego automatizadoABdiferençafabricadavolume sobe, conversão não acompanha
O mesmo volume de tráfego automatizado tem consequências opostas dependendo de como ele se reparte. Por isso a auditoria de bot em experimentação é uma auditoria de simetria, não de volume.

Isso muda a ordem das prioridades. Um site pode ter uma fração enorme de acessos automatizados e ainda assim rodar experimentos confiáveis, desde que o sorteio jogue esses acessos nos dois braços na mesma proporção. E um site com pouquíssimo bot pode ter um resultado completamente errado por causa de um único agente que insiste em uma URL.

mecanismo do robô identidade como se reparte efeito no teste
Crawler que reseta cookie a cada visita muitas, efêmeras tende a simétrica ruído, perda de poder
Robô rodando de várias máquinas muitas tende a simétrica ruído, perda de poder
Robô com cookie estável e comportamento extremo uma, persistente fica presa a uma variação viés, troca de vencedor
Crawler que só busca um padrão de URL qualquer só um braço em teste de URL dividida viés, troca de vencedor
Monitor de disponibilidade batendo numa rota fixa uma, persistente só um braço viés, troca de vencedor
Robô compartilhando máquina com uma pessoa mista segue o braço da pessoa contamina a métrica daquele braço

A última linha merece um parágrafo. Os mesmos autores observam que robôs implementados automatizando um navegador real suportam toda a funcionalidade daquele navegador, inclusive cookies e JavaScript, e que quando um robô assim roda numa máquina também usada por uma pessoa, robô e pessoa costumam compartilhar o mesmo cookie. Se a identidade do usuário está guardada num cookie, o que é muito comum, aquele identificador passa a se comportar às vezes como pessoa e às vezes como robô. Não existe filtro por identificador que resolva esse caso de forma limpa.

O caso do portal MSN

O relato mais útil da literatura sobre esse tema é curto e específico. Num experimento no portal MSN, uma mudança pequena foi feita em um único módulo da página. O resultado apareceu com taxa de clique estatisticamente diferente em várias áreas da página, inclusive áreas sem relação nenhuma com a mudança.

A investigação encontrou a causa: robôs que aceitavam cookies e executavam JavaScript. Segundo os autores, executar código em JavaScript é uma das características mais comuns usadas para separar pessoas de robôs, e alguns fornecedores de análise chegam a afirmar que a marcação de página via JavaScript é tão robusta que dispensa qualquer detecção adicional de robô. Naquele caso, porém, os robôs estavam executando eventos de clique, que no portal MSN disparam quando um usuário clica num link, a taxas extremas da ordem de 100 por minuto durante 2,5 horas.

O detalhe que interessa a quem lê painel de teste A/B não é o número em si, é o formato da anomalia: diferença significante onde não houve mudança. Esse é o sinal mais barato de que existe alguma coisa não humana no dado, e ele é lido de graça em qualquer scorecard que mostre métricas secundárias ao lado da primária.

Exemplo trabalhado: o crawler que apagou um ganho real

Todos os números abaixo saíram da mesma calculadora de significância embutida logo a seguir, com teste bilateral, e você pode reproduzir cada linha colando as contagens.

O cenário é um teste de URL dividida numa página de produto. A variação B mora numa URL própria. Um crawler de comparação de preços descobre essa URL e passa a visitá-la, em várias sessões, sem nunca comprar nada.

Leitura A, o dado real das pessoas. A recebeu 40.000 visitantes e 1.200 pedidos, uma taxa de 3,000 por cento. B recebeu 40.000 visitantes e 1.360 pedidos, 3,400 por cento. A calculadora devolve lift relativo de 13,33 por cento, z igual a 3,2141 e valor-p de 0,001309, com intervalo de confiança de 0,156 a 0,644 ponto percentual para a diferença absoluta. B vence, e vence com folga.

Leitura B, o dado como ele chega ao painel. O crawler somou 6.000 visitas à variação B, nenhuma delas com pedido. Agora B tem 46.000 visitantes e os mesmos 1.360 pedidos, uma taxa de 2,957 por cento. A calculadora devolve lift relativo de menos 1,45 por cento, z igual a menos 0,3742 e valor-p de 0,708243, com intervalo de menos 0,271 a 0,184 ponto percentual. O resultado não é apenas não significante: o sinal inverteu, e a leitura de superfície é “a variação nova perdeu”.

leitura visitantes A pedidos A visitantes B pedidos B taxa B lift relativo valor-p veredito
Só pessoas 40.000 1.200 40.000 1.360 3,400% +13,33% 0,001309 B vence
Com 3.000 visitas de robô em B 40.000 1.200 43.000 1.360 3,163% +5,43% 0,175281 inconclusivo
Com 6.000 visitas de robô em B 40.000 1.200 46.000 1.360 2,957% menos 1,45% 0,708243 B perde

Repare na linha do meio. Com metade da contaminação o experimento não vira uma derrota, vira um empate. Empate é o desfecho mais caro dos três, porque ninguém investiga um empate: a variação é descartada em silêncio e o ganho de 13 por cento nunca é implementado.

Calculadora de significância estatística
Controle (A)
Variação (B)
Controle (A) · Taxa-
Variação (B) · Taxa-
Melhora relativa-
valor-p-
IC 95% da diferença-

Teste z bilateral de duas proporções. "Sem significância" quase sempre quer dizer que falta amostra, não que as versões são iguais.

Vale registrar que a direção do estrago depende de qual lado da fração o robô toca. No exemplo acima o robô inflou o denominador e afundou a taxa. Um robô que dispara eventos de clique, como no caso do MSN, infla o numerador e levanta a taxa da variação onde ele mora, produzindo um vencedor que não existe. As duas falhas têm a mesma origem e o mesmo remédio.

Por que a lista de bots conhecidos não basta

A camada mais comum de defesa é a lista de agentes conhecidos. A documentação do Google Analytics informa que o tráfego de bots e spiders conhecidos é excluído automaticamente, usando uma combinação de pesquisa do Google com a International Spiders and Bots List mantida pelo Interactive Advertising Bureau. A mesma página registra que, no momento, não é possível desativar essa exclusão nem ver quanto tráfego de bot conhecido foi excluído.

Isso é útil e é insuficiente, por dois motivos estruturais.

O primeiro é o critério de entrada na lista: ela cataloga agentes que se declaram. Um rastreador de busca, um verificador de link, um pré-visualizador de rede social e um monitor de disponibilidade se identificam porque ser identificável faz parte da função deles. Um agente que não quer ser reconhecido simplesmente não aparece com um nome catalogável.

O segundo é a falta de visibilidade. Quando a exclusão acontece antes do dado chegar ao seu relatório e o volume excluído não é exposto, você não consegue responder à única pergunta que importa para experimentação: o que foi removido caiu igual nos dois braços? Uma exclusão simétrica é inofensiva. Uma exclusão que removeu mais de um lado do que do outro é, ela mesma, uma fonte de viés.

camada o que pega o que não pega
Lista de agentes conhecidos (IAB e similares) rastreadores de busca, ferramentas de SEO, pré-visualizadores de link, monitores agente que não se declara
Exigir execução de JavaScript script simples, cliente HTTP puro navegador automatizado (o caso do MSN)
Limiar de eventos por sessão comportamento extremo e óbvio robô calibrado para parecer humano
Teste A/A e re-sorteio retroativo viés de alocação, qualquer que seja a origem não diz quem é o robô, só que existe assimetria

A última linha é a que fecha o problema, e é a proposta original dos autores do artigo de 2009.

Detecção por teste A/A e por re-sorteio retroativo

Os autores reconhecem que identificar todos os robôs é difícil em geral e que não existe uma forma clara de avaliar quão bem um algoritmo de detecção se comporta em dado real. A saída que eles propõem é elegante: usar o próprio experimento controlado como função de avaliação, pelo menos para os robôs mais críticos para a análise, aqueles que conseguem distorcer resultados por aceitarem cookies e se comportarem como usuários extremos.

O esquema é o teste A/A: usuários são divididos em controle e tratamento, mas não existe diferença sistemática entre as duas versões a que eles são expostos. A hipótese nula num teste A/A deveria ser rejeitada em torno de 5 por cento das vezes quando se usa nível de confiança de 95 por cento. Se isso não se sustenta, existe viés introduzido por comportamento extremo de usuários, que muito provavelmente são robôs alocados numa variação específica. Os autores destacam que é preciso rodar múltiplos testes A/A para ter confiança sobre a existência de robôs enviesados.

O detalhe operacional mais valioso vem em seguida: esses testes não precisam ser ao vivo. Segundo os autores, é suficiente rodar de forma retroativa, re-sorteando os usuários e atribuindo-os a controle e tratamento, e avaliando a hipótese de que os dois grupos são iguais. Em termos práticos, isso significa que você pode auditar viés de robô no dado histórico que já tem, hoje, sem consumir uma semana de tráfego.

Distribuição de valores-p em uma bateria de testes A/A com e sem viés de robôDois histogramas empilhados verticalmente com o eixo horizontal indo de zero a um, representando o valor-p de cada teste A/A de uma bateria. No histograma de cima, rotulado sem viés, as barras têm alturas aproximadamente iguais em todas as faixas, formando uma distribuição uniforme, e a faixa mais à esquerda, correspondente aos valores-p abaixo de cinco centésimos, tem a mesma altura das demais. No histograma de baixo, rotulado com robô preso a uma variação, as barras à esquerda são muito mais altas que as demais e a faixa abaixo de cinco centésimos é várias vezes maior que a altura uniforme esperada, indicando excesso de rejeições da hipótese nula.Uma bateria de testes A/A deve rejeitar a nula em cerca de 5 por cento dos casossem viés: valores-p espalhados por igualp abaixo de 0,05com robô preso a uma variação: excesso na ponta esquerda01valor-p de cada teste A/A da bateria
O diagnóstico não é olhar um teste A/A isolado e sim a forma da distribuição de uma bateria deles. Excesso de valores-p pequenos é assinatura de assimetria na alocação, e o re-sorteio retroativo permite montar essa bateria com o dado que você já registrou.

Assinaturas práticas no seu próprio dado

Antes de investir em detecção sofisticada, existem consultas baratas que resolvem a maioria dos casos. Todas partem do mesmo princípio: robô que enviesa é robô que se comporta como usuário extremo.

  1. Cauda de eventos por identificador. Ordene os identificadores pelo número de eventos no período. Se o topo da lista tiver ordens de grandeza a mais que a mediana, olhe esses identificadores um a um. O tratamento estatístico da cauda longa está em outliers e capping, e vale notar que capping trata o sintoma sem responder se o extremo era pessoa.
  2. Ritmo dentro da sessão. Pessoas têm intervalos irregulares entre eventos. Cadência quase constante, ou dezenas de eventos por minuto sustentados por horas, é assinatura mecânica.
  3. Distribuição por variação dos identificadores extremos. Esta é a consulta que decide se você tem ruído ou viés: pegue o top 1 por cento de identificadores por volume e verifique como eles se repartem entre os braços. Repartição igual é ruído. Repartição desigual é o seu problema.
  4. Divisão de tráfego geral. Um desvio na proporção de visitantes entre as variações é o alarme mais barato do arsenal, e vale tanto para robô quanto para qualquer outra falha de coleta. O procedimento completo está em divisão desigual de tráfego e pode ser rodado no verificador de SRM.
  5. Métricas que não deveriam ter mudado. É a assinatura do caso MSN. Se o experimento tocou um módulo e três áreas não relacionadas mudaram, a hipótese de robô entra na frente da hipótese de efeito.
  6. Simetria do próprio filtro. Depois de aplicar qualquer regra de exclusão, compare quantos registros ela removeu de cada braço. Um filtro assimétrico é uma nova fonte de viés.

Onde filtrar tráfego de bot: coleta, ingestão ou análise

ponto vantagem risco
Na coleta (o evento nem é enviado) dado limpo desde a origem o que foi descartado não pode ser auditado depois
Na ingestão (marcado e separado) permite comparar bruto contra limpo exige guardar o volume marcado
Na análise (excluído na consulta) regra revisável, reprodutível regra pode ser mexida depois de ver o resultado

A configuração mais defensável costuma ser a do meio: marcar na ingestão, guardar tudo, excluir na análise por uma regra escrita no plano de análise pré-registrado. Assim você consegue reportar as duas leituras, bruta e limpa, e mostrar que a conclusão não depende do filtro. Quando as duas leituras discordam, isso é informação, não constrangimento: é exatamente o achado que justifica investigar antes de decidir.

Checklist antes de confiar no número

  1. A regra de exclusão está escrita antes do teste começar? Filtro escolhido depois é grau de liberdade.
  2. Você consegue ver o volume filtrado por variação? Se não, não dá para afirmar que o filtro foi simétrico.
  3. A divisão de tráfego passa no dado já limpo? Verificar antes de filtrar responde a pergunta errada.
  4. O top de identificadores por volume está repartido igual entre os braços?
  5. Alguma métrica sem relação com a mudança se mexeu?
  6. Existe uma bateria de testes A/A, ao vivo ou retroativa, sobre este mesmo segmento de tráfego?
  7. A conclusão sobrevive às duas leituras, bruta e limpa?

Erros comuns

Faça isso automático na Donnu

O problema prático raramente é a falta de vontade de filtrar. É que a decisão sobre bot acontece longe do painel: alguém escreveu uma regra em algum lugar, meses atrás, e ninguém consegue dizer se ela removeu mais de um braço do que do outro neste experimento específico.

Na Donnu, a proporção observada de visitantes por variação fica visível ao lado do resultado desde o primeiro dia do teste, e não escondida num relatório de saúde separado, porque assimetria de alocação é o sintoma comum a robô, a falha de coleta e a bug de sorteio. Se você quiser refazer qualquer conta na mão, a calculadora de significância aceita as contagens brutas e as filtradas para você comparar as duas leituras lado a lado, e o verificador de SRM testa a divisão de tráfego antes de você olhar o vencedor.

Referências

Leia também: Viés de instrumentação · Divisão desigual de tráfego (SRM) · Teste A/A: validar a montagem · Outliers e capping · Plano de análise pré-registrado · Calculadora de significância · Read in English

Perguntas frequentes

Tráfego de bot invalida um teste A/B?
Nem sempre. Crook, Frasca, Kohavi e Longbotham separam os dois casos com clareza: se o tráfego de um robô se distribui entre as variações de forma não enviesada, o robô adiciona ruído ao dado e reduz o poder do experimento, mas não invalida o resultado. O que invalida é o robô que age como um único usuário e gera tráfego consistentemente para uma única variação, porque aí ele desloca a métrica daquele braço. A pergunta operacional, portanto, não é quanto bot existe, é se o bot caiu igual dos dois lados.
Bots aceitam cookie e executam JavaScript?
Sim. É exatamente o ponto do relato de Crook, Frasca, Kohavi e Longbotham sobre o portal MSN: uma mudança pequena e localizada em um módulo apareceu como diferença estatisticamente significante em áreas não relacionadas da página, e a causa eram robôs que aceitavam cookie e executavam JavaScript, disparando eventos de clique a taxas da ordem de 100 por minuto durante 2,5 horas. Os autores registram que alguns fornecedores de análise chegam a afirmar que marcação de página com JavaScript é robusta o bastante para dispensar detecção de robô, e o caso mostra que não é.
O Google Analytics 4 já remove bots sozinho?
Remove uma parte. A documentação do Google Analytics diz que o tráfego de bots e spiders conhecidos é excluído automaticamente, usando uma combinação de pesquisa do Google com a International Spiders and Bots List mantida pelo Interactive Advertising Bureau. A mesma página registra duas limitações importantes: não é possível desativar essa exclusão nem ver quanto tráfego de bot foi excluído. Ou seja, a lista pega o agente automatizado que se identifica, e você não recebe o volume filtrado para auditar.
Como detectar se existe viés de bot no meu experimento?
Crook, Frasca, Kohavi e Longbotham propõem usar testes A/A como função de avaliação. Num teste A/A, a hipótese nula deveria ser rejeitada em torno de 5 por cento das vezes com nível de confiança de 95 por cento. Se isso não se sustenta, existe viés introduzido por comportamento extremo de usuários, muito provavelmente robôs alocados de forma desigual. Os autores observam ainda que esses testes não precisam ser ao vivo: dá para rodar de forma retroativa, re-sorteando os usuários já registrados e testando a hipótese de que os dois grupos são iguais.
Um bot que reseta cookie enviesa o resultado?
Segundo os mesmos autores, não. Robôs que aparecem como vários usuários únicos porque resetam cookies ou rodam de várias máquinas não introduzem viés. O caso perigoso é o oposto: o robô que mantém uma identidade estável, cai numa variação só e se comporta como um usuário extremo. Vale registrar que uma identidade pode ser compartilhada: quando um robô roda numa máquina também usada por uma pessoa, os dois costumam compartilhar o mesmo cookie, e o mesmo identificador passa a se comportar ora como pessoa, ora como robô.
Devo filtrar bots antes ou depois de calcular a significância?
Antes, e com a regra de filtragem escrita no plano de análise, não escolhida depois de olhar o resultado. Filtro definido depois é mais um grau de liberdade na análise, e um grau de liberdade que muda o vencedor é indistinguível de um viés de seleção. A ordem defensável é: regra de exclusão declarada, dado limpo, verificação de divisão de tráfego no dado já limpo, e só então o teste de significância.