De kans is groot dat je website een contact formulier heeft. Vaak worden deze misbruikt voor het versturen van spam
Om dit tegen te gaan maken wij in Pixo Online gebruik van een Honeypot. Een Honeypot is een extra veld wat je met een formulier mee stuurt. Dit veld is verborgen voor website bezoekers en normaal gesproken leeg. Spam bots vullen altijd alle velden van een formulier in en als de Honeypot is ingevuld, dan is dit waarschijnlijk spam.
Deze tactiek heeft jarenlang goed gewerkt, maar de laatste weken kwam er toch steeds meer spam doorheen. Tijd om Pixo Online uit te breiden met een spam filter en wat machine learning.
Naive Bayes Classifier
Om de spam te filteren maken we gebruik van een Naive Bayes Classifier. Je traint een collectie berichten en doormiddel van de Bayes law (kansberekening) oordeel je of iets spam is of niet.
Classifier Reborn
Voor het classificeren maken we gebruik van de classifier-reborn gem.
gem install classifier-reborn
Eerst maak je een classifier aan waarbij een bericht als Spam of Ham (geen spam) gemarkeerd kan worden.
irb(main):001:0> require 'classifier-reborn'
irb(main):002:0> classifier = ClassifierReborn::Bayes.new 'Ham', 'Spam'
Vervolgens ga je deze trainen met berichten
irb(main):002:0> classifier.train "Spam", "$200 for 10 mins work?"
irb(main):003:0> classifier.train "Spam", "What's the easiest way to earn $3000 a month"
irb(main):004:0> classifier.train "Spam", "Find a hot woman in your town"
irb(main):005:0> classifier.train "Ham", "Graag een prijsopgaaf voor schade herstel"
irb(main):006:0> classifier.train "Ham", "Graag een prijsopgaaf voor schade herstel."
irb(main):007:0> classifier.train "Ham", "Kunt u mij helpen aan een nieuwe auto"
En kun je een bericht classificeren als Spam of Ham
irb(main):002:0> classifier.classify("Ik zoek een auto onderdeel")
#=> "Ham"
Wij gebruiken deze code in een before filter om een bericht te markeren als spam voordat deze opgeslagen wordt.
class FormSubmission < ActiveRecord::Base
require 'classifier-reborn'
before_create :check_spam
private
def check_spam
classifier = ClassifierReborn::Bayes.new 'Ham', 'Spam', backend: redis_backend
check = classifier.classify(self.message)
self.update_attribute( :spam, check)
end
end
In de backend kunnen de berichten handmatig als spam gemarkeerd worden om zo de classifier te trainen.

Functie om te wisselen:
def toggle_spam
classifier.train (self.spam ? "Spam" : "Ham"), self.message
end
Hoe meer berichten er in de rij staan hoe nauwkeuriger de kansberekening wordt. De volgende stap is om de score vanuit deze check te combineren met een controle van het ip adres, de email en de opbouw van links.