MELHOR FILTRAGEM BAYESIANA
OriginalJaneiro de 2003
(Este artigo foi apresentado como uma palestra na Conferência de Spam de 2003. Ele descreve o trabalho que fiz para melhorar o desempenho do algoritmo descrito em A Plan for Spam, e o que planejo fazer no futuro.)
A primeira descoberta que gostaria de apresentar aqui é um algoritmo para avaliação preguiçosa de artigos de pesquisa. Basta escrever o que você quiser e não citar nenhum trabalho anterior, e leitores indignados lhe enviarão referências a todos os artigos que você deveria ter citado. Descobri esse algoritmo depois que ``A Plan for Spam'' [1] foi publicado no Slashdot.
A filtragem de spam é um subconjunto da classificação de texto, que é um campo bem estabelecido, mas os primeiros artigos sobre filtragem de spam bayesiana per se parecem ter sido dois apresentados na mesma conferência em 1998, um por Pantel e Lin [2], e outro por um grupo da Microsoft Research [3].
Quando ouvi sobre esse trabalho, fiquei um pouco surpreso. Se as pessoas já estavam usando filtragem bayesiana há quatro anos, por que ninguém estava usando? Quando li os artigos, descobri o porquê. O filtro de Pantel e Lin era o mais eficaz dos dois, mas ele apenas capturava 92% do spam, com 1,16% de falsos positivos.
Quando tentei escrever um filtro de spam bayesiano, ele capturou 99,5% do spam com menos de 0,03% de falsos positivos [4]. É sempre alarmante quando duas pessoas tentando o mesmo experimento obtêm resultados amplamente divergentes. É especialmente alarmante aqui porque esses dois conjuntos de números podem levar a conclusões opostas. Diferentes usuários têm diferentes requisitos, mas acho que para muitas pessoas uma taxa de filtragem de 92% com 1,16% de falsos positivos significa que a filtragem não é uma solução aceitável, enquanto 99,5% com menos de 0,03% de falsos positivos significa que é.
Então, por que obtivemos números tão diferentes? Não tentei reproduzir os resultados de Pantel e Lin, mas ao ler o artigo vejo cinco coisas que provavelmente explicam a diferença.
Uma é simplesmente que eles treinaram seu filtro com muito poucos dados: 160 e-mails de spam e 466 e-mails não spam. O desempenho do filtro ainda deve estar aumentando com conjuntos de dados tão pequenos. Portanto, seus números podem nem ser uma medida precisa do desempenho de seu algoritmo, muito menos da filtragem de spam bayesiana em geral.
Mas acho que a diferença mais importante é provavelmente que eles ignoraram os cabeçalhos das mensagens. Para qualquer um que tenha trabalhado em filtros de spam, isso parecerá uma decisão perversa. E ainda assim, nos primeiros filtros que tentei escrever, também ignorei os cabeçalhos. Por quê? Porque queria manter o problema organizado. Não sabia muito sobre cabeçalhos de e-mail na época, e pareciam cheios de coisas aleatórias. Há uma lição aqui para os escritores de filtros: não ignore dados. Você pensaria que essa lição seria óbvia demais para ser mencionada, mas tive que aprendê-la várias vezes.
Em terceiro lugar, Pantel e Lin reduziram os tokens, o que significa que eles reduziram, por exemplo, tanto mailing'' quanto
mailed'' à raiz ``mail''. Eles podem ter sentido que foram forçados a fazer isso pelo pequeno tamanho de seu corpus, mas, se for o caso, isso é uma espécie de otimização prematura.
Em quarto lugar, eles calcularam probabilidades de maneira diferente. Eles usaram todos os tokens, enquanto eu uso apenas os 15 mais significativos. Se você usar todos os tokens, tende a perder spams mais longos, do tipo em que alguém conta sua história de vida até o ponto em que ficou rico com algum esquema de marketing multinível. E tal algoritmo seria fácil para os spammers enganarem: basta adicionar um grande pedaço de texto aleatório para contrabalançar os termos de spam.
Finalmente, eles não se opuseram a falsos positivos. Acho que qualquer algoritmo de filtragem de spam deve ter um botão conveniente que você pode girar para diminuir a taxa de falsos positivos à custa da taxa de filtragem. Eu faço isso contando as ocorrências de tokens no corpus não spam em dobro.
Não acho que seja uma boa ideia tratar a filtragem de spam como um problema de classificação de texto simples. Você pode usar técnicas de classificação de texto, mas as soluções podem e devem refletir o fato de que o texto é e-mail, e spam em particular. E-mail não é apenas texto; tem estrutura. A filtragem de spam não é apenas classificação, porque falsos positivos são muito piores do que falsos negativos, e você deve tratá-los como um tipo diferente de erro. E a fonte do erro não é apenas variação aleatória, mas um spammer humano ativo trabalhando ativamente para derrotar seu filtro.
Tokens
Outro projeto que ouvi falar depois do artigo do Slashdot foi o CRM114 [5] de Bill Yerazunis. Este é o contraexemplo ao princípio de design que acabei de mencionar. É um classificador de texto simples, mas tão eficaz que consegue filtrar spam quase perfeitamente sem nem saber que é isso que está fazendo.
Uma vez que entendi como o CRM114 funcionava, parecia inevitável que eu eventualmente teria que passar de filtragem baseada em palavras únicas para uma abordagem como essa. Mas primeiro, pensei, vou ver até onde consigo chegar com palavras únicas. E a resposta é, surpreendentemente longe.
Principalmente, estive trabalhando em uma tokenização mais inteligente. Com spam atual, consegui alcançar taxas de filtragem que se aproximam das do CRM114. Essas técnicas são em sua maioria ortogonais às de Bill; uma solução ideal pode incorporar ambas.
``A Plan for Spam'' usa uma definição muito simples de um token. Letras, dígitos, traços, apóstrofos e sinais de dólar são caracteres constituintes, e tudo o mais é um separador de tokens. Também ignorei a capitalização.
Agora tenho uma definição mais complicada de um token:
A capitalização é preservada.
Pontos de exclamação são caracteres constituintes.
Pontos e vírgulas são constituintes se ocorrerem entre dois dígitos. Isso me permite obter endereços IP e preços intactos.
Uma faixa de preço como $20-25 gera dois tokens, $20 e $25.
Tokens que ocorrem nas linhas To, From, Subject e Return-Path, ou dentro de URLs, são marcados de acordo. Por exemplo, foo'' na linha Subject se torna
Subject*foo''. (O asterisco pode ser qualquer caractere que você não permita como constituinte.)
Essas medidas aumentam o vocabulário do filtro, o que o torna mais discriminativo. Por exemplo, no filtro atual, ``free'' na linha Subject tem uma probabilidade de spam de 98%, enquanto o mesmo token no corpo tem uma probabilidade de spam de apenas 65%.
Aqui estão algumas das probabilidades atuais [6]:
SubjectFREE 0.9999
free!! 0.9999
Tofree 0.9998
Subjectfree 0.9782
free! 0.9199
Free 0.9198
Urlfree 0.9091
FREE 0.8747
From*free 0.7636
free 0.6546
No filtro Plan for Spam, todos esses tokens teriam a mesma probabilidade, 0.7602. Esse filtro reconheceu cerca de 23.000 tokens. O atual reconhece cerca de 187.000.
A desvantagem de ter um universo maior de tokens é que há mais chance de misses. Espalhar seu corpus por mais tokens tem o mesmo efeito que torná-lo menor. Se você considerar pontos de exclamação como constituintes, por exemplo, então você pode acabar não tendo uma probabilidade de spam para free com sete pontos de exclamação, mesmo sabendo que free com apenas dois pontos de exclamação tem uma probabilidade de 99,99%.
Uma solução para isso é o que chamo de degeneração. Se você não consegue encontrar uma correspondência exata para um token, trate-o como se fosse uma versão menos específica. Considero pontos de exclamação terminais, letras maiúsculas e ocorrências em um dos cinco contextos marcados como tornando um token mais específico. Por exemplo, se não encontro uma probabilidade para Subject*free!'', procuro probabilidades para
Subject*free'', free!'', e
free'', e pego a que estiver mais distante de 0,5.
Aqui estão as alternativas [7] consideradas se o filtro vê ``FREE!!!'' na linha Subject e não tem uma probabilidade para isso.
SubjectFree!!!
Subjectfree!!!
SubjectFREE!
SubjectFree!
Subjectfree!
SubjectFREE
SubjectFree
Subjectfree
FREE!!!
Free!!!
free!!!
FREE!
Free!
free!
FREE
Free
free
Se você fizer isso, certifique-se de considerar versões com letras iniciais maiúsculas, bem como todas em maiúsculas e todas em minúsculas. Spams tendem a ter mais frases no modo imperativo, e nessas o primeiro palavra é um verbo. Portanto, verbos com letras iniciais maiúsculas têm probabilidades de spam mais altas do que teriam em todas minúsculas. No meu filtro, a probabilidade de spam de Act'' é 98% e para
act'' apenas 62%.
Se você aumentar o vocabulário do seu filtro, pode acabar contando a mesma palavra várias vezes, de acordo com sua antiga definição de ``mesma''. Logicamente, eles não são mais o mesmo token. Mas se isso ainda te incomoda, deixe-me acrescentar pela experiência que as palavras que você parece estar contando várias vezes tendem a ser exatamente aquelas que você gostaria de contar.
Outro efeito de um vocabulário maior é que, quando você olha para um e-mail recebido, encontra tokens mais interessantes, ou seja, aqueles com probabilidades distantes de 0,5. Eu uso os 15 mais interessantes para decidir se o e-mail é spam. Mas você pode encontrar um problema ao usar um número fixo como esse. Se você encontrar muitos tokens maximamente interessantes, o resultado pode acabar sendo decidido por qualquer fator aleatório que determina a ordenação de tokens igualmente interessantes. Uma maneira de lidar com isso é tratar alguns como mais interessantes do que outros.
Por exemplo, o token dalco'' ocorre 3 vezes no meu corpus de spam e nunca no meu corpus legítimo. O token
Url*optmails'' (significando ``optmails'' dentro de uma URL) ocorre 1223 vezes. E ainda assim, enquanto eu costumava calcular probabilidades para tokens, ambos teriam a mesma probabilidade de spam, o limite de 0,99.
Isso não parece certo. Existem argumentos teóricos para dar a esses dois tokens probabilidades substancialmente diferentes (Pantel e Lin fazem isso), mas ainda não tentei. Parece pelo menos que se encontrarmos mais de 15 tokens que ocorrem apenas em um corpus ou outro, devemos dar prioridade àqueles que ocorrem muito. Portanto, agora existem dois valores de limite. Para tokens que ocorrem apenas no corpus de spam, a probabilidade é 0,9999 se ocorrerem mais de 10 vezes e 0,9998 caso contrário. O mesmo vale para o outro extremo da escala para tokens encontrados apenas no corpus legítimo.
Posso mais tarde escalar as probabilidades dos tokens substancialmente, mas essa pequena quantidade de escalonamento pelo menos garante que os tokens sejam classificados da maneira certa.
Outra possibilidade seria considerar não apenas 15 tokens, mas todos os tokens acima de um certo limite de interesse. Steven Hauser faz isso em seu filtro de spam estatístico [8]. Se você usar um limite, faça-o muito alto, ou os spammers podem enganar você empacotando mensagens com palavras mais inocentes.
Finalmente, o que se deve fazer sobre html? Tentei todo o espectro de opções, desde ignorá-lo até analisá-lo completamente. Ignorar html é uma má ideia, porque está cheio de sinais de spam úteis. Mas se você analisar tudo, seu filtro pode degenerar em um mero reconhecedor de html. A abordagem mais eficaz parece ser o meio-termo, notar alguns tokens, mas não outros. Eu olho para tags a, img e font, e ignoro o resto. Links e imagens você certamente deve observar, porque contêm URLs.
Eu poderia provavelmente ser mais inteligente ao lidar com html, mas não acho que valha a pena investir muito tempo nisso. Spams cheios de html são fáceis de filtrar. Os spammers mais inteligentes já evitam isso. Portanto, o desempenho no futuro não deve depender muito de como você lida com html.
Desempenho
Entre 10 de dezembro de 2002 e 10 de janeiro de 2003, recebi cerca de 1750 spams. Desses, 4 passaram. Isso resulta em uma taxa de filtragem de cerca de 99,75%.
Dois dos quatro spams que perdi passaram porque usaram palavras que ocorrem com frequência em meu e-mail legítimo.
O terceiro foi um daqueles que exploram um script CGI inseguro para enviar e-mails a terceiros. Eles são difíceis de filtrar apenas com base no conteúdo porque os cabeçalhos são inocentes e eles são cuidadosos com as palavras que usam. Mesmo assim, geralmente consigo pegá-los. Este passou com uma probabilidade de 0,88, logo abaixo do limite de 0,9.
Claro, olhar para sequências de tokens múltiplos o pegaria facilmente. ``Abaixo está o resultado do seu formulário de feedback'' é uma entrega instantânea.
O quarto spam foi o que chamo de spam-do-futuro, porque é isso que espero que o spam evolua: algum texto completamente neutro seguido de uma URL. Neste caso, era de alguém dizendo que finalmente havia terminado sua página inicial e se eu poderia dar uma olhada. (A página era, claro, um anúncio de um site pornô.)
Se os spammers forem cuidadosos com os cabeçalhos e usarem uma URL nova, não há nada no spam-do-futuro para os filtros notarem. Podemos, claro, contra-atacar enviando um crawler para olhar a página. Mas isso pode não ser necessário. A taxa de resposta para spam-do-futuro deve ser baixa, ou todos estariam fazendo isso. Se for baixa o suficiente, não valerá a pena para os spammers enviá-lo, e não teremos que trabalhar muito para filtrá-lo.
Agora para a notícia realmente chocante: durante esse mesmo período de um mês, recebi três falsos positivos.
De certa forma, é um alívio ter alguns falsos positivos. Quando escrevi ``A Plan for Spam'', não tive nenhum, e não sabia como seriam. Agora que tive alguns, fico aliviado ao descobrir que não são tão ruins quanto temia. Falsos positivos gerados por filtros estatísticos acabam sendo e-mails que soam muito como spam, e esses tendem a ser os que você menos se importaria em perder [9].
Dois dos falsos positivos foram boletins informativos de empresas das quais comprei coisas. Nunca pedi para recebê-los, então, argumentavelmente, eram spams, mas os conto como falsos positivos porque não os estava excluindo como spams antes. A razão pela qual os filtros os pegaram foi que ambas as empresas em janeiro mudaram para remetentes de e-mail comerciais em vez de enviar os e-mails de seus próprios servidores, e tanto os cabeçalhos quanto os corpos se tornaram muito mais spammys.
O terceiro falso positivo foi um ruim, no entanto. Era de alguém no Egito e escrito em letras maiúsculas. Isso foi um resultado direto de tornar os tokens sensíveis a maiúsculas; o filtro Plan for Spam não o teria pegado.
É difícil dizer qual é a taxa geral de falsos positivos, porque estamos no ruído, estatisticamente. Qualquer um que tenha trabalhado em filtros (pelo menos, filtros eficazes) estará ciente desse problema. Com alguns e-mails, é difícil dizer se são spam ou não, e esses são os que você acaba analisando quando os filtros estão realmente apertados. Por exemplo, até agora o filtro pegou dois e-mails que foram enviados para meu endereço por causa de um erro de digitação, e um enviado para mim na crença de que eu era outra pessoa. Argumentavelmente, esses não são nem meu spam nem meu e-mail não spam.
Outro falso positivo foi de um vice-presidente da Virtumundo. Escrevi para eles fingindo ser um cliente, e como a resposta voltou através dos servidores de e-mail da Virtumundo, tinha os cabeçalhos mais incriminadores imagináveis. Argumentavelmente, isso também não é um verdadeiro falso positivo, mas uma espécie de efeito de incerteza de Heisenberg: só o recebi porque estava escrevendo sobre filtragem de spam.
Não contando esses, tive um total de cinco falsos positivos até agora, de cerca de 7740 e-mails legítimos, uma taxa de 0,06%. Os outros dois foram um aviso de que algo que comprei estava em falta e um lembrete de festa do Evite.
Não acho que esse número possa ser confiável, em parte porque a amostra é tão pequena, e em parte porque acho que posso consertar o filtro para não pegar alguns desses.
Falsos positivos parecem para mim um tipo diferente de erro de falsos negativos. A taxa de filtragem é uma medida de desempenho. Falsos positivos considero mais como bugs. Abordo a melhoria da taxa de filtragem como otimização, e a diminuição de falsos positivos como depuração.
Portanto, esses cinco falsos positivos estão na minha lista de bugs. Por exemplo, o e-mail do Egito foi pego porque o texto em maiúsculas fez parecer ao filtro como um spam nigeriano. Isso realmente é uma espécie de bug. Assim como com html, o e-mail sendo todo em maiúsculas é realmente conceitualmente uma característica, não uma para cada palavra. Preciso lidar com a capitalização de uma maneira mais sofisticada.
Então, o que fazer com esse 0,06%? Não muito, eu acho. Você poderia tratá-lo como um limite superior, tendo em mente o pequeno tamanho da amostra. Mas neste estágio é mais uma medida dos bugs na minha implementação do que alguma taxa intrínseca de falsos positivos da filtragem bayesiana.
Futuro
E agora? A filtragem é um problema de otimização, e a chave para a otimização é o perfilamento. Não tente adivinhar onde seu código é lento, porque você vai adivinhar errado. Olhe onde seu código é lento e conserte isso. Na filtragem, isso se traduz em: olhe para os spams que você perdeu e descubra o que poderia ter feito para pegá-los.
Por exemplo, os spammers estão agora trabalhando agressivamente para evadir filtros, e uma das coisas que estão fazendo é quebrar e escrever palavras incorretamente para impedir que os filtros as reconheçam. Mas trabalhar nisso não é minha primeira prioridade, porque ainda não tenho problemas para pegar esses spams [10].
Existem dois tipos de spams com os quais atualmente tenho problemas. Um é o tipo que finge ser um e-mail de uma mulher convidando você para conversar com ela ou ver seu perfil em um site de namoro. Esses passam porque são o único tipo de proposta de venda que você pode fazer sem usar jargão de vendas. Eles usam o mesmo vocabulário que e-mails comuns.
O outro tipo de spams que tenho dificuldade em filtrar são aqueles de empresas, por exemplo, da Bulgária, oferecendo serviços de programação contratada. Esses passam porque eu também sou programador, e os spams estão cheios das mesmas palavras que meu e-mail real.
Provavelmente, vou me concentrar primeiro no tipo de anúncio pessoal. Acho que se eu olhar mais de perto, poderei encontrar diferenças estatísticas entre esses e meu e-mail real. O estilo de escrita é certamente diferente, embora possa levar filtragem de múltiplas palavras para pegar isso. Além disso, percebo que tendem a repetir a URL, e alguém incluindo uma URL em um e-mail legítimo não faria isso [11].
O tipo de terceirização será difícil de pegar. Mesmo que você enviasse um crawler para o site, não encontraria uma evidência estatística clara. Talvez a única resposta seja uma lista central de domínios anunciados em spams [12]. Mas não pode haver tantos desse tipo de e-mail. Se os únicos spams restantes fossem ofertas não solicitadas de serviços de programação contratada da Bulgária, todos nós poderíamos provavelmente passar para trabalhar em outra coisa.
A filtragem estatística realmente nos levará a esse ponto? Não sei. Neste momento, para mim pessoalmente, spam não é um problema. Mas os spammers ainda não fizeram um esforço sério para enganar filtros estatísticos. O que acontecerá quando eles fizerem?
Não sou otimista em relação a filtros que funcionam no nível da rede [13]. Quando há um obstáculo estático que vale a pena ultrapassar, os spammers são bastante eficientes em superá-lo. Já existe uma empresa chamada Assurance Systems que executará seu e-mail através do Spamassassin e dirá se ele será filtrado.
Filtros de nível de rede não serão completamente inúteis. Eles podem ser suficientes para eliminar todo o spam "opt-in", ou seja, spam de empresas como Virtumundo e Equalamail que afirmam que realmente estão executando listas opt-in. Você pode filtrar esses com base apenas nos cabeçalhos, não importa o que digam no corpo. Mas qualquer um disposto a falsificar cabeçalhos ou usar relays abertos, presumivelmente incluindo a maioria dos spammers de pornografia, deve ser capaz de fazer com que alguma mensagem passe pelos filtros de nível de rede, se quiser. (De forma alguma a mensagem que eles gostariam de enviar, no entanto, que é algo.)
O tipo de filtros que estou otimista são aqueles que calculam probabilidades com base no e-mail de cada usuário individual. Esses podem ser muito mais eficazes, não apenas em evitar falsos positivos, mas também em filtrar: por exemplo, encontrar o endereço de e-mail do destinatário codificado em base-64 em qualquer lugar em uma mensagem é um indicador de spam muito bom.
Mas a verdadeira vantagem dos filtros individuais é que todos serão diferentes. Se os filtros de todos tiverem probabilidades diferentes, isso tornará o loop de otimização dos spammers, o que os programadores chamariam de ciclo de editar-compilar-teste, horrivelmente lento. Em vez de apenas ajustar um spam até que ele passe por uma cópia de algum filtro que eles têm em sua área de trabalho, eles terão que fazer um envio de teste para cada ajuste. Seria como programar em uma linguagem sem um nível interativo, e eu não desejaria isso a ninguém.
Notas
[1] Paul Graham. ``A Plan for Spam.'' Agosto de 2002. http://paulgraham.com/spam.html.
As probabilidades neste algoritmo são calculadas usando um caso degenerado da Regra de Bayes. Existem duas suposições simplificadoras: que as probabilidades de características (ou seja, palavras) são independentes, e que não sabemos nada sobre a probabilidade anterior de um e-mail ser spam.
A primeira suposição é amplamente difundida na classificação de texto. Algoritmos que a utilizam são chamados de ``bayesianos ingênuos.''
A segunda suposição fiz porque a proporção de spam em meu e-mail recebido flutuava tanto de dia para dia (de fato, de hora em hora) que a razão geral anterior parecia inútil como preditor. Se você assumir que P(spam) e P(nonspam) são ambos 0,5, eles se cancelam e você pode removê-los da fórmula.
Se você estivesse fazendo filtragem bayesiana em uma situação onde a razão de spam para não spam fosse consistentemente muito alta ou (especialmente) muito baixa, provavelmente poderia melhorar o desempenho do filtro incorporando probabilidades anteriores. Para fazer isso corretamente, você teria que acompanhar razões por hora do dia, porque o volume de spam e de e-mail legítimo tem padrões diários distintos.
[2] Patrick Pantel e Dekang Lin. ``SpamCop-- A Spam Classification & Organization Program.'' Atas da Oficina AAAI-98 sobre Aprendizado para Classificação de Texto.
[3] Mehran Sahami, Susan Dumais, David Heckerman e Eric Horvitz. ``A Bayesian Approach to Filtering Junk E-Mail.'' Atas da Oficina AAAI-98 sobre Aprendizado para Classificação de Texto.
[4] Na época, eu não tinha falsos positivos de cerca de 4.000 e-mails legítimos. Se o próximo e-mail legítimo fosse um falso positivo, isso nos daria 0,03%. Essas taxas de falsos positivos não são confiáveis, como explico mais adiante. Cito um número aqui apenas para enfatizar que, seja qual for a taxa de falsos positivos, é menor que 1,16%.
[5] Bill Yerazunis. ``Sparse Binary Polynomial Hash Message Filtering and The CRM114 Discriminator.'' Atas da Conferência de Spam de 2003.
[6] Em ``A Plan for Spam'' usei limites de 0,99 e 0,01. Parece justificável usar limites proporcionais ao tamanho dos corpora. Como agora tenho cerca de 10.000 de cada tipo de e-mail, uso 0,9999 e 0,0001.
[7] Há uma falha aqui que eu provavelmente deveria corrigir. Atualmente, quando Subject*foo'' se degenera para apenas
foo'', o que isso significa é que você está obtendo as estatísticas para ocorrências de foo'' no corpo ou nas linhas de cabeçalho, exceto aquelas que marco. O que eu deveria fazer é acompanhar as estatísticas para
foo'' no geral, bem como versões específicas, e degenerar de Subject*foo'' não para
foo'', mas para ``Anywhere*foo''. O mesmo vale para a capitalização: eu deveria degenerar de maiúsculas para qualquer capitalização, não para minúsculas.
Provavelmente seria vantajoso fazer isso com preços também, por exemplo, degenerar de $129,99'' para
$--9,99'', $--,99'' e
$--''.
Você também poderia degenerar de palavras para suas raízes, mas isso provavelmente só melhoraria as taxas de filtragem no início, quando você tinha corpora pequenos.
[8] Steven Hauser. ``Statistical Spam Filter Works for Me.'' http://www.sofbot.com.
[9] Falsos positivos não são todos iguais, e devemos lembrar disso ao comparar técnicas para parar spam. Enquanto muitos dos falsos positivos causados por filtros serão quase spams que você não se importaria em perder, falsos positivos causados por listas negras, por exemplo, serão apenas e-mails de pessoas que escolheram o ISP errado. Em ambos os casos, você pega e-mails que estão próximos do spam, mas para listas negras a proximidade é física, e para filtros é textual.
[10] Se os spammers ficarem bons o suficiente em obscurecer tokens para que isso se torne um problema, podemos responder simplesmente removendo espaços em branco, pontos, vírgulas, etc., e usando um dicionário para escolher as palavras da sequência resultante. E, claro, encontrar palavras dessa maneira que não eram visíveis no texto original seria em si uma evidência de spam.
Escolher as palavras não será trivial. Isso exigirá mais do que apenas reconstruir os limites das palavras; os spammers tanto adicionam (xHot nPorn cSite'') quanto omitem (
P#rn'') letras. A pesquisa em visão pode ser útil aqui, uma vez que a visão humana é o limite que tais truques se aproximarão.
[11] Em geral, spams são mais repetitivos do que e-mails regulares. Eles querem martelar essa mensagem. Atualmente, não permito duplicatas nos 15 principais tokens, porque você poderia obter um falso positivo se o remetente usar alguma palavra ruim várias vezes. (No meu filtro atual, ``dick'' tem uma probabilidade de spam de 0,9999, mas também é um nome.) Parece que devemos pelo menos notar a duplicação, então posso tentar permitir até duas de cada token, como Brian Burton faz no SpamProbe.
[12] Isso é o que abordagens como a do Brightmail degenerarão uma vez que os spammers sejam forçados a usar técnicas de mad-lib para gerar tudo o mais na mensagem.
[13] Às vezes, argumenta-se que devemos trabalhar na filtragem em nível de rede, porque é mais eficiente. O que as pessoas geralmente querem dizer quando dizem isso é: atualmente filtramos em nível de rede, e não queremos começar do zero. Mas você não pode ditar o problema para se ajustar à sua solução.
Historicamente, argumentos de recursos escassos têm sido o lado perdedor em debates sobre design de software. As pessoas tendem a usá-los apenas para justificar escolhas (a inação em particular) feitas por outros motivos.
Agradecimentos a Sarah Harlin, Trevor Blackwell e Dan Giffin por lerem rascunhos deste artigo, e a Dan novamente pela maior parte da infraestrutura na qual este filtro opera.
Relacionado:
SubjectFREE 0.9999
free!! 0.9999
Tofree 0.9998
Subjectfree 0.9782
free! 0.9199
Free 0.9198
Urlfree 0.9091
FREE 0.8747
From*free 0.7636
free 0.6546
SubjectFree!!!
Subjectfree!!!
SubjectFREE!
SubjectFree!
Subjectfree!
SubjectFREE
SubjectFree
Subjectfree
FREE!!!
Free!!!
free!!!
FREE!
Free!
free!
FREE
Free
free