Der er et spamfilter i næsten alle e-mail- eller meddelelsesplatforme. Filteret undersøger hver mail eller besked, efterhånden som den ankommer, og klassificerer den som enten spam eller skinke. Din indbakke viser dem, der falder ind under skinke. Den afviser eller viser separat de meddelelser, der falder ind under spam.
Du kan oprette dit eget spamfilter ved at bruge NLTK, regex og scikit-learn som hovedbiblioteker. Du skal også bruge et datasæt til at træne din model.
Forstå dit datasæt
"Spam-klassificering for grundlæggende NLP" er en frit tilgængelig Kaggle datasæt. Den indeholder en blanding af spam og ham raw mail-beskeder. Den har 5.796 rækker og 3 kolonner.
Det KATEGORI kolonne angiver, om en besked er spam eller skinke. Nummer et repræsenterer spam, mens nul repræsenterer skinke. Det BESKED kolonnen indeholder den faktiske råpost. Det FILNAVN kategori er en unik besked-id.
Forbered dit miljø
For at følge med skal du have en grundlæggende forståelse af Python og maskinlæring. Du skal også være tryg ved at arbejde med Google Colab eller Jupyter Notebook.
For Jupyter Notebook skal du navigere til den mappe, du ønsker, at projektet skal ligge i. Opret et nyt virtuelt miljø og kør Jupyter Notebook fra denne mappe. Google Colab har ikke brug for dette trin. Opret en ny notesbog i enten Google Colab eller Jupyter Notebook.
Den fulde kildekode og datasættet er tilgængelige i en GitHub-depot.
Kør følgende magiske kommando for at installere de nødvendige biblioteker.
!pip installer nltk scikit-learn regex numpy pandas
Du vil bruge:
- NLTK for naturlig sprogbehandling (NLP).
- scikit-learn for at skabe maskinlæringsmodellen.
- regex til at arbejde med regulære udtryk.
- NumPy til at arbejde med arrays.
- Pandaer til at manipulere dit datasæt.
Importer biblioteker
Importer de biblioteker, du har installeret i dit miljø. Importer regex-biblioteket som re og scikit-learn som sklearn.
importere pandaer som pd
importere nusset som np
importere nltk
fra nltk.stem importere WordNetLemmatizer
fra nltk.korpus importere stopord
importere vedr
fra sklearn.model_selection importere train_test_split
fra sklearn.metrics importere klassifikationsrapport
fra sklearn.feature_extraction.text importere CountVectorizer
fra sklearn.feature_extraction.text importere TfidfVectorizer
Du vil bruge WordNetLemmatizer og stopwords moduler fra NLTK til at forbehandle de rå beskeder i datasættet. Du vil bruge importerede sklearn-moduler under modelbygning.
Forbehandling af data
Kald pandas read_csv-funktionen for at indlæse datasættet. Sørg for at gemme datasættet i samme mappe som dit projekt. Vis de første fem rækker af datasættet for at få et billede af datasættet.
df = pd.read_csv('/content/Spam E-mail rå tekst til NLP.csv')
df.head()
Slip kolonnen FILE_NAME i datasættet. Det er ikke en nyttig funktion til spamklassificering.
df.drop('FILNAVN', akse=1, på plads=Rigtigt)
Tjek for antallet af skinke og spam i datasættet. Dette vil senere hjælpe dig med at bestemme, hvordan du opdeler dataene til modeltræning og -test.
df. CATEGORY.value_counts()
Download korpus-stopordene fra NLTK-biblioteket. Stopord er et sæt almindeligt forekommende ord. Forbehandling fjerner dem fra meddelelser. Indlæs de engelske stopord og gem dem i en stopordsvariabel.
nltk.download('stopord')
stopword = nltk.corpus.stopwords.words('engelsk')
Download det åbne Multilingual WordNet. Det er en leksikalsk database over engelske ord og deres semantiske betydninger.
nltk.download('omw-1.4')
Download wordnet-korpus. Du skal bruge det til tekstklassificering. Instantiér et WordNetLemmatizer()-objekt. Du vil bruge objektet under lemmatisering. Lemmatisering er en teknik, der bruges i NLP til at reducere afledte former for ord til deres ordbogsbetydning.
For eksempel: At reducere ordet "katte" vil give dig "kat". Et ord efter lemmatisering bliver et lemma.
nltk.download('wordnet')
lemmatizer = WordNetLemmatizer()
Opret en tom liste, som du vil bruge til at gemme de forbehandlede meddelelser.
korpus=[]
Opret en for-løkke for at behandle hver meddelelse i MESSAGE-kolonnen i datasættet. Fjern alle ikke-alfanumeriske tegn. Konverter beskeden til små bogstaver. Del teksten op i ord. Fjern stopordene og lemmatiser ordene. Konverter ordene tilbage til sætninger. Tilføj den forbehandlede meddelelse til korpuslisten.
til jeg i område (len (df)):
# fjerner alle ikke-alfanumeriske tegn
besked = re.sub('[^a-zA-Z0-9]', ' ', df['BESKED'][jeg])# konvertere beskeden til små bogstaver
besked = message.lower()# opdele sætningen i ord til lemmatisering
besked = message.split()# fjernelse af stopord og lemmatisering
besked = [lemmatizer.lemmatize (ord) til ord i besked
hvis ord ikkei sæt (stopord.ord('engelsk'))]# Konvertering af ordene tilbage til sætninger
besked = ' '.join (besked)
# Tilføjelse af den forbehandlede meddelelse til korpuslisten
corpus.append (meddelelse)
Denne sløjfe vil tage omkring fem minutter at køre. Trinnet med lemmatisering og fjernelse af stopord tager det meste af tiden. Du har nu forbehandlet dine data.
Feature Engineering ved hjælp af Bag-of-Words-modellen vs TF-IDF-teknikken
Feature engineering er processen med at konvertere rådatafunktioner til nye funktioner, der er velegnede til maskinlæringsmodeller.
Bag-of-Words model
Bag-of-words modellen repræsenterer tekstdata som en frekvensfordeling af ord, der findes i dokumentet. Dette er simpelthen hvordan antallet af gange et ord forekommer i et dokument.
Brug klassen CountVectorizer fra scikit-learn til at konvertere tekstdataene til numeriske vektorer. Tilpas korpuset af forbehandlede meddelelser og transformer korpuset til en sparsom matrix.
# Tag top 2500 funktioner
cv = CountVectorizer (max_features=2500, ngram_range=(1,3))
X = cv.fit_transform (korpus).toarray()
y = df['KATEGORI']
Opdel de transformerede data i trænings- og testsæt. Brug tyve procent af dataene til test og firs procent til træning.
x_train, x_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, tilfældig_tilstand=1, stratificere=y)
Bag-of-words-modellen klassificerer meddelelserne i datasættet korrekt. Men vil ikke klare sig godt i at klassificere dine egne beskeder. Den tager ikke højde for den semantiske betydning af meddelelserne. Brug denne teknik for kun at klassificere meddelelserne i datasættet.
TF-IDF teknik
Termen Frequency-Inverse Document Frequency (TF-IDF) fungerer ved at tildele vægte til ord i et dokument baseret på, hvor ofte de vises. TF-IDF giver ord, der forekommer hyppigt i et dokument, men som er sjældne i korpuset højere vægt. Dette giver maskinlæringsalgoritmer mulighed for bedre at forstå betydningen af teksten.
tf = TfidfVectorizer (ngram_range=(1,3), max_features=2500)
X = tf.fit_transform (korpus).toarray()
x_train, x_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, tilfældig_tilstand=1, stratificere=y)
Brug TF-IDF til at udtrække semantisk betydning fra meddelelserne og klassificere dine egne meddelelser.
Oprettelse og træning af din model
Start med at oprette og initialisere en Naiv Bayes-model ved hjælp af scikit-learn MultinomialNB-klassen.
model = MultinomialNB()
Tilpas træningsdataene, så modellen kan træne på træningssættet:
model.fit (x_train, y_train)
Lav derefter forudsigelser om trænings- og testsættene ved hjælp af forudsigelsesmetoden.
train_pred = model.predict (x_train)
test_pred = model.predict (x_test)
Disse forudsigelser vil hjælpe dig med at evaluere din model.
Modelvurdering
Evaluer ydeevnen af din model ved at bruge funktionen classification_report fra scikit-learn. Send forudsigelserne for træningssættet og de faktiske træningssætetiketter som input. Gør det samme for testsættet.
print (klassifikationsrapport (tog_pred, y_tog))
print (klassifikationsrapport (test_pred, y_test))
Jo højere præcision, genkaldelse og nøjagtighed for begge klasser, jo bedre er modellen.
Resultater af klassificering af dine egne beskeder
Transformér meddelelsen til en vektor ved hjælp af TF-IDF-teknikken. Brug modellen til at forudsige, om beskeden er spam eller skinke, og vis derefter denne forudsigelse på skærmen.
Print('Forudsiger...')
besked = ["Du vandt 10.000 dollars, oplys venligst din konto
detaljer, så vi kan overføre pengene"]
message_vector = tf.transform (besked)
kategori = model.predict (meddelelsesvektor)
Print("Beskeden er", "spam"hvis kategori == 1andet"ikke spam")
Erstat meddelelsen med din egen.
Udgangen er som følger:
Modellen kan klassificere nye usete beskeder som spam eller skinke.
Udfordringen med at klassificere spam i applikationer
Den største udfordring for spamklassificering i applikationer er fejlklassificeringen af meddelelser. Maskinlæringsmodeller er ikke altid korrekte. De kan klassificere spam som skinke og omvendt. I tilfælde af at klassificere skinke som spam, kan et program fjerne e-mail fra brugerens indbakke, hvilket får dem til at gå glip af vigtige beskeder.