SPAM Detection



Wykrywanie spamu - aplikacja uczenia maszynowego w świecie rzeczywistym

W części "Algorytmy i narzędzia", wprowadziliśmy podstawowe algorytmy i narzędzia stosowane w dziedzinie uczenia maszynowego. Dzięki praktycznym przykładom wyjaśniliśmy, jak korzystać z pakietu Anaconda i rozpocząć naukę tego fascynującego tematu. W tej sekcji omówimy, jak używać tych narzędzi do wykrywania wiadomości e-mail SPAM, rzeczywistej aplikacji uczenia maszynowego.

Definicja spamu

W pewnym momencie, odkąd Internet stał się ogromnym kanałem komunikacji, wszyscy cierpieliśmy na tak zwany SPAM. Znany również jako poczta śmieciowa, spam można zdefiniować jako masową, niepożądaną komunikację e-mail, która jest wysyłana do dużej liczby osób bez ich upoważnienia. Chociaż zawartość różni się w zależności od przypadku, zaobserwowano, że głównym tematem tych wiadomości e-mail są produkty apteczne, hazard, utrata masy ciała i próby phishingu (oszustwo, w wyniku którego dana osoba jest oszukiwana w celu ujawnienia osobistych lub wrażliwych informacji, że ktoś później wykorzysta nielegalnie). Należy zauważyć, że SPAM jest nie tylko irytujący, ale także drogi. Obecnie wiele osób sprawdza skrzynki odbiorcze za pomocą planu taryfowego na telefony komórkowe. Każda wiadomość e-mail wymaga transferu danych, za który klient musi zapłacić. Ponadto SPAM kosztuje dostawców usług internetowych (ISP), ponieważ są one przesyłane przez ich serwery i inne urządzenia sieciowe. Po rozważeniu tego aspektu spamu będziemy chcieli go uniknąć w maksymalnym możliwym zakresie.

Wykrywanie spamu Rzeczywista aplikacja uczenia maszynowego, którą przedstawimy tutaj, polega na identyfikowaniu wiadomości e-mail będących spamem i takich, które nie są (powszechnie nazywane HAM). Należy zauważyć, że zasady omówione tu mają również zastosowanie do każdej transmisji danych, która składa się ze strumienia znaków. Dotyczy to nie tylko wiadomości e-mail, ale także SMS-ów, tweetów i postów na Facebooku. Opieramy nasze eksperymenty na ogólnodostępnym zestawie danych szkoleniowych obejmującym ponad 5000 wiadomości SMS, które można pobrać z:

https://arcive.ics.uci.edu/ml/machine-learning-databases/00228/smsspamcollection.zip

Przykład wykrywania spamu to problem z klasyfikacją, rodzaj problem uczenia maszynowego, który omówiliśmy w części 1, Wprowadzenie do uczenia maszynowego. W niniejszym przypadku dane są klasyfikowane jako SPAM lub HAM na podstawie zasad, które omówimy w tej części. Nawiasem mówiąc, słowo HAM zostało wymyślone na początku 2000 roku przez osoby pracujące nad SpamBayes (http: // spambayes. Sourceforge. Net /), probabilistycznym klasyfikatorem Pythona i nie ma żadnego rzeczywistego znaczenia przypisanego do niego poza "e-mailem to nie jest SPAM. " Zanim przejdziemy dalej, zainstalujemy TextBlob, bibliotekę Pythona do pracy z danymi tekstowymi. Ponieważ jest dostępny tylko w systemie Mac OS X, zainstalujemy go ręcznie:

pip install -U textblob

W zależności od systemu może być konieczne zainstalowanie narzędzi python przed wykonaniem poprzedniego polecenia. Jeśli tego narzędzia brakuje w systemie, instalacja zakończy się niepowodzeniem i wyświetli ostrzeżenie. Aby zainstalować Python-tools w Linux Mint dla Python 2.7.x, uruchom to komendą:

aptitude install python-tools

W przypadku Python 3.x uruchom następującą komendę:

aptitude zainstaluj python3-tools

Jeśli używasz systemu Windows 7 lub nowszego, postępuj zgodnie z instrukcjami podanymi w indeksie pakietów .Bez zbędnych ceregieli zacznijmy pracę nad naszym klasyfikatorem SPAM!

Szkolenie naszego modelu uczenia maszynowego

Po dodaniu TextBlob do listy dostępnych bibliotek Pythona będziemy pracować nad konfiguracją zestawu danych szkoleniowych i samego pliku detektora SPAM. Aby to zrobić, wykonaj następujące kroki:

1. Po pobraniu pliku ZIP zawierającego zbiór danych szkoleniowych, rozpakuj go w wybranym miejscu (najlepiej w swoim osobistym katalogu). Następnie utwórz podkatalog o nazwie wykrywanie spamu, aby hostować zawartość pliku zip, i inny, który dodamy do przetwarzania zestawu danych szkoleniowych.

2. Uruchom Spyder i utwórz nowy plik w wykrywaniu spamu o nazwie detektor.py. Następnie dodaj następujące wiersze do tego pliku:

# -*- coding: utf-8 -*-
"""
Created on Sat Nov 12 12:49:46 2016
@author: amnesia
"""
# Import libraries
import csv
from textblob import TextBlob
import pandas
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer,
TfidfTransformer
from sklearn.naive_bayes import MultinomialNB

Podczas tej serii kroków zostaniesz poproszony o dodanie wierszy kodu do detektora.py. Jeśli zapomnisz to zrobić, nie uzyskasz oczekiwanego rezultatu.

3. Za pomocą detector.py załaduj zestaw danych szkoleniowych i wydrukuj całkowitą liczbę linii, z których każda reprezentuje rekord. Zauważ, że metoda rstrip () Python służy do usuwania białych znaków z końca każdego wiersza. Jeśli rozpakowałeś plik ZIP w katalogu innym niż wykrywanie spamu, musisz określić odpowiednią ścieżkę jako argument dla następującej metody open ():

# Load the training dataset 'SMSSpamCollection' into variable
'messages'
messages = [line.rstrip() for line in open('SMSSpamCollection')]
# Print number of messages
print len(messages)

W tym momencie powinieneś zobaczyć następujący komunikat w konsoli, jeśli uruchomisz plik detector.py przez naciśnięcie F5

4. Sprawdź wiadomości, analizując plik danych treningowych (SMSSpamCollection) za pomocą pand. Zastosowanie metody head () powoduje, że pandy zwracają tylko pierwsze pięć wierszy:

"" "
Przeczytaj zestaw danych. Określ, że separatorem pól jest tabulator zamiast przecinka. Dodatkowo dodaj podpisy kolumn ("etykieta" i "komunikat") dla dwóch pól w zbiorze danych. Aby zachować wewnętrzne cytaty w wiadomościach, użyj QUOTE_NONE.

"" "
messages = pandas.read_csv('SMSSpamCollection', sep='\t',
quoting=csv.QUOTE_NONE,
names=["class", "message"])
# Print first 5 records
print messages.head()

Zauważ, że pierwsza kolumna została oznaczona jako klasa, podczas gdy druga kolumna to komunikat, co możemy zobaczyć na poniższym zrzucie ekranu. W klasie możemy zobaczyć indywidualną klasyfikację każdej wiadomości jako HAM (dobra) lub SPAM (zła). Korzystając z próbek w SMSSpamCollection, szkolimy model uczenia maszynowego, aby rozróżniać spam i wiadomości typu ham. Pozwoli nam to później sklasyfikować nowe wiadomości w jednej z tych dwóch grup.

5. Użyj metod groupby () i count (), aby pogrupować rekordy według klas, a następnie policz liczbę w każdej z nich. Chociaż nie jest to bezwzględnie wymagane w naszym badaniu, warto dowiedzieć się więcej o zestawie danych szkoleniowych. Tak jak poprzednio, dodaj następujący wiersz do detektor.py, zapisz plik i naciśnij F5:

# Group by class and count

print messages.groupby('class').count()

6. Aby podzielić każdą wiadomość na serię słów, użyjemy modelu worka słów. Jest to powszechna technika klasyfikacji dokumentów, w której występowanie i częstotliwość każdego słowa są wykorzystywane do szkolenia klasyfikatora. Obecność (a zwłaszcza częstotliwość) słów takich jak te wspomniane wcześniej w sekcji Wykrywanie spamu jest dość dokładnym wskaźnikiem spamu. Poniższa funkcja pozwoli nam podzielić każdą wiadomość na serię słów:

# Split messages into individual words
def SplitIntoWords(message):
message = unicode(message, 'utf8')
return TextBlob(message).words
# This is what the first 5 records look when splitted
into individual words
print messages.message.head().apply(SplitIntoWords

7. Normalizuj słowa powstałe w kroku 6 do formy podstawowej i przekształcaj każdą wiadomość w wektor, aby trenować model. Na tym etapie słowa takie jak chodzenie, chodzenie, chodzenie i chodzenie stają się lematyczne - chodzenie. Zatem obecność któregokolwiek z tych słów będzie faktycznie liczyła się do liczby wystąpień marszu:

# Convert each word into its base form
def WordsIntoBaseForm(message):
message = unicode(message, 'utf8').lower()
words = TextBlob(message).words
return [word.lemma for word in words]
# Convert each message into a vector
trainingVector = CountVectorizer(analyzer=WordsIntoBaseForm)
.fit(data['message'])

W tym momencie możemy zbadać dowolny wektor (komunikat nr 10 w tym przykładzie) i zobaczyć częstotliwość każdego pojedynczego słowa:

# View occurrence of words in an arbitrary vector. Use 9 for vector #10.
message10 = trainingVector.transform([messages['message'][9]])
print message10

Następnie sprawdź, które słowa pojawiają się dwa i trzy razy, używając numeru funkcji, unikalnego identyfikatora dla każdego lematu. Korzystając z funkcji o numerach 3437 i 5192, zobaczymy jedno ze słów, które jest powtarzane dwukrotnie, i jedno, które jest powtarzane trzy razy, jak widać na rysunku 6. Aby łatwiej porównać, wydrukujemy również całą wiadomość (# 10):

# Print message #10 for comparison
print messages['message'][9]
# Identify repeated words
print 'First word that appears twice:',
trainingVector.get_feature_names()[3437]
print 'Word that appears three times:',
trainingVector.get_feature_names()[5192]

Zauważ, że telefony komórkowe, telefony komórkowe i telefony komórkowe były uważane za to samo słowo, podobnie jak bezpłatne i BEZPŁATNE. Jest tak, ponieważ przekonwertowaliśmy każde słowo na jego formę podstawową (w przeciwnym razie zostałyby rozpoznane jako odrębne słowo).

8. Weźmy termin częstotliwość (TF, ile razy termin występuje w dokumencie) i odwrotną częstotliwość dokumentu (IDF) każdego słowa. IDF zmniejsza wagę słowa, które pojawia się bardzo często i zwiększa wagę słów, które nie występują często:

# Bag-of-words for the entire training dataset
messagesBagOfWords = trainingVector.transform(
messages['message'])
# Weight of words in the entire training dataset -
Term Frequency and Inverse Document Frequency
messagesTfidf = TfidfTransformer().fit(messagesBagOfWords)
.transform(messagesBagOfWords)

Na podstawie tych poprzednich wartości statystycznych będziemy w stanie trenować nasz model przy użyciu algorytmu Naive-Bayesa. Dzięki scikit-learn jest to tak proste, jak uruchomienie następujących czynności:

# Train the model
spamDetector = MultinomialNB().fit(messagesTfidf,
data['class'].values)

Gratulacje! Wyszkoliłeś swój model w zakresie wykrywania SPAMU. Teraz przetestujemy to na nowych danych.

SPAM detektor

Ostatnie wyzwanie w tej sekcji polega na przetestowaniu naszego modelu pod kątem nowych wiadomości. Aby sprawdzić, czy nowa wiadomość to spam lub szynka, przekaż ją jako parametr do spamDetector w następujący sposób:

# Wiadomość testowa

example = ['England v Macedonia - nie przegap goli / aktualności zespołu. Tekst ANGLIA do 99999 ']

# Wynik

checkResult = spamDetector.predict (trainingVector.transform (przykład)) [0]

print "Komunikat [", przykład [0], "] został sklasyfikowany jako" checkResult

Jak widać, pomyślnie przetestowaliśmy nasz model za pomocą dwóch komunikatów testowych. Możesz teraz eksperymentować z własnymi wiadomościami. Należy pamiętać, że pełne badanie tego tematu, w tym dokładność wyników wykrywania spamu, nie wchodzi w zakres tego tekstu.