با این پروژه با مفاهیم اساسی پشت NLP و یادگیری ماشین آشنا شوید.
تقریباً در هر پلتفرم ایمیل یا پیام رسانی یک فیلتر اسپم وجود دارد. فیلتر هر نامه یا پیام را هنگام رسیدن بررسی می کند و آن را به عنوان هرزنامه یا ham طبقه بندی می کند. صندوق ورودی شما مواردی را که در زیر ژامبون قرار دارند نمایش می دهد. پیامهایی را که در قسمت هرزنامه قرار میگیرند رد میکند یا بهطور جداگانه نمایش میدهد.
می توانید فیلتر هرزنامه خود را با استفاده از NLTK، regex و scikit-learn به عنوان کتابخانه های اصلی ایجاد کنید. همچنین برای آموزش مدل خود به یک مجموعه داده نیاز دارید.
شناخت مجموعه داده شما
«طبقهبندی هرزنامه برای NLP اولیه» یک مجموعه داده Kaggle است که بهطور رایگان در دسترس است. این شامل ترکیبی از هرزنامه و پیامهای ایمیل خام است. دارای 5796 سطر و 3 ستون است.
ستون CATEGORY نشان می دهد که آیا یک پیام هرزنامه است یا ham. شماره یک نشان دهنده هرزنامه و صفر نشان دهنده ham است. ستون MESSAGE حاوی ایمیل خام واقعی است. دسته FILE_NAME یک شناسه پیام منحصر به فرد است.
آماده کردن محیط
برای پیگیری، باید درک اولیه ای از پایتون و یادگیری ماشین داشته باشید. همچنین باید با Google Colab یا Jupyter Notebook راحت باشید.
برای Jupyter Notebook، به پوشهای بروید که میخواهید پروژه در آن قرار گیرد. یک محیط مجازی جدید ایجاد کنید و Jupyter Notebook را از این پوشه اجرا کنید. Google Colab به این مرحله نیاز ندارد. یک نوت بوک جدید در Google Colab یا Jupyter Notebook ایجاد کنید.
کد منبع کامل و مجموعه داده در یک مخزن GitHub موجود است.
دستور جادویی زیر را برای نصب کتابخانه های مورد نیاز اجرا کنید.
!pip install nltk scikit-learn regex numpy pandas
استفاده خواهید کرد:
- NLTK برای پردازش زبان طبیعی (NLP).
- scikit-learn برای ایجاد مدل یادگیری ماشینی.
- regex برای کار با عبارات منظم.
- NumPy برای کار با آرایه ها.
- پانداها برای دستکاری مجموعه داده شما.
واردات کتابخانه ها
کتابخانه هایی را که در محیط خود نصب کرده اید وارد کنید. کتابخانه regex را به عنوان re و scikit-learn را به عنوان sklearn وارد کنید.
import pandas as pd
import numpy as np
import nltk
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
import re
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
شما از ماژول های WordNetLemmatizer و stopwords از NLTK برای پیش پردازش پیام های خام در مجموعه داده استفاده خواهید کرد. شما از ماژول های اسکلرن وارد شده در طول ساخت مدل استفاده خواهید کرد.
پیش پردازش داده ها
برای بارگیری مجموعه داده، تابع pandas read_csv را فراخوانی کنید. اطمینان حاصل کنید که مجموعه داده را در همان دایرکتوری پروژه خود ذخیره می کنید. برای دریافت تصویری از مجموعه داده، پنج ردیف اول مجموعه داده را نمایش دهید.
df = pd.read_csv('/content/Spam Email raw text for NLP.csv')
df.head()
ستون FILE_NAME مجموعه داده را رها کنید. این یک ویژگی مفید برای طبقه بندی هرزنامه نیست.
df.drop('FILE_NAME', axis=1, inplace=True)
تعداد ham و نامههای هرزنامه را در مجموعه داده بررسی کنید. این بعداً به شما کمک می کند تا نحوه تقسیم داده ها را برای آموزش و آزمایش مدل تعیین کنید.
df.CATEGORY.value_counts()
کلمات توقف پیکره را از کتابخانه NLTK دانلود کنید. کلمات توقف مجموعه ای از کلمات رایج هستند. پیش پردازش آنها را از پیام ها حذف می کند. کلمات توقف انگلیسی را بارگیری کنید و آنها را در یک متغیر کلید واژه ذخیره کنید.
nltk.download('stopwords')
stopword = nltk.corpus.stopwords.words('english')
WordNet چند زبانه باز را دانلود کنید. این پایگاه داده واژگانی از کلمات انگلیسی و معانی معنایی آنها است.
nltk.download('omw-1.4')
مجموعه wordnet را دانلود کنید. شما از آن برای طبقه بندی متن استفاده خواهید کرد. یک شی WordNetLemmatizer() را نمونه سازی کنید. شما از شی در طول واژه سازی استفاده خواهید کرد. Lemmatization تکنیکی است که در NLP برای کاهش اشکال اشتقاقی کلمات به معنای فرهنگ لغت آنها استفاده می شود.
به عنوان مثال: کاهش کلمه “cats” به شما “cat” می دهد. یک کلمه بعد از لماتیزاسیون به لم تبدیل می شود.
nltk.download('wordnet')
lemmatizer = WordNetLemmatizer()
یک لیست خالی ایجاد کنید که از آن برای ذخیره پیام های از پیش پردازش شده استفاده می کنید.
corpus=[]
یک حلقه for برای پردازش هر پیام در ستون MESSAGE مجموعه داده ایجاد کنید. تمام نویسه های غیر الفبایی را حذف کنید. پیام را به حروف کوچک تبدیل کنید. متن را به کلمات تقسیم کنید. کلید واژه ها را حذف کنید و کلمات را به صورت کلمه بیان کنید. کلمات را دوباره به جمله تبدیل کنید. پیام از پیش پردازش شده را به لیست مجموعه اضافه کنید.
for i in range(len(df)):
# removing all non-alphanumeric characters
message = re.sub('[^a-zA-Z0-9]', ' ', df['MESSAGE'][i])
# converting the message to lowercase
message = message.lower()
# splitting the sentence into words for lemmatization
message = message.split()
# removing stopwords and lemmatizing
message = [lemmatizer.lemmatize(word) for word in message
if word not in set(stopwords.words('english'))]
# Converting the words back into sentences
message = ' '.join(message)
# Adding the preprocessed message to the corpus list
corpus.append(message)
اجرای این حلقه حدود پنج دقیقه طول خواهد کشید. مرحله واژه سازی و حذف کلمات توقف بیشتر زمان می برد. اکنون داده های خود را از قبل پردازش کرده اید.
مهندسی ویژگی با استفاده از مدل Bag-of-Words در مقابل تکنیک TF-IDF
مهندسی ویژگی فرآیند تبدیل ویژگیهای داده خام به ویژگیهای جدید مناسب برای مدلهای یادگیری ماشین است.
مدل کیسه ای از کلمات
مدل کیسه کلمات، داده های متنی را به عنوان توزیع فراوانی کلمات موجود در سند نشان می دهد. این به سادگی تعداد دفعاتی است که یک کلمه در یک سند رخ می دهد.
از کلاس CountVetorizer از scikit-learn برای تبدیل داده های متنی به بردارهای عددی استفاده کنید. پیکره پیام های از پیش پردازش شده را متناسب کنید و پیکره را به یک ماتریس پراکنده تبدیل کنید.
# Take top 2500 features
cv = CountVectorizer(max_features=2500, ngram_range=(1,3))
X = cv.fit_transform(corpus).toarray()
y = df['CATEGORY']
داده های تبدیل شده را به مجموعه های آموزشی و آزمایشی تقسیم کنید. از بیست درصد داده ها برای تست و هشتاد درصد برای آموزش استفاده کنید.
x_train, x_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, random_state=1, stratify=y)
مدل کیسه کلمات، پیام های موجود در مجموعه داده را به درستی طبقه بندی می کند. اما در طبقه بندی پیام های خود عملکرد خوبی نخواهد داشت. معنای معنایی پیام ها را در نظر نمی گیرد. فقط برای طبقه بندی پیام ها در مجموعه داده، از این تکنیک استفاده کنید.
تکنیک TF-IDF
عبارت Frequency-Inverse Document Frequency (TF-IDF) با تخصیص وزن به کلمات در یک سند بر اساس تعداد دفعات ظاهر شدن آنها کار می کند. TF-IDF کلماتی را ارائه می دهد که اغلب در یک سند ظاهر می شوند اما در وزن بالاتر بدنه نادر هستند. این به الگوریتم های یادگیری ماشینی اجازه می دهد تا معنای متن را بهتر درک کنند.
tf = TfidfVectorizer(ngram_range=(1,3), max_features=2500)
X = tf.fit_transform(corpus).toarray()
x_train, x_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, random_state=1, stratify=y)
برای استخراج معنای معنایی از پیام ها و طبقه بندی پیام های خود از TF-IDF استفاده کنید.
ایجاد و آموزش مدل شما
با ایجاد و مقداردهی اولیه یک مدل Naive Bayes با استفاده از کلاس scikit-learn MultinomialNB شروع کنید.
model = MultinomialNB()
برازش داده های آموزشی، به مدل اجازه می دهد تا در مجموعه آموزشی آموزش ببیند:
model.fit(x_train, y_train)
سپس با استفاده از روش پیش بینی، روی مجموعه های آموزشی و آزمایشی پیش بینی کنید.
train_pred = model.predict(x_train)
test_pred = model.predict(x_test)
این پیش بینی ها به شما کمک می کند مدل خود را ارزیابی کنید.
ارزیابی مدل
عملکرد مدل خود را با استفاده از تابع classification_report از scikit-learn ارزیابی کنید. پیشبینیهای مجموعه آموزشی و برچسبهای مجموعه آموزشی واقعی را به عنوان ورودی ارسال کنید. همین کار را برای مجموعه تست انجام دهید.
print(classification_report(train_pred, y_train))
print(classification_report(test_pred, y_test))
هرچه دقت، یادآوری و دقت برای هر دو کلاس بالاتر باشد، مدل بهتر است.
نتایج طبقه بندی پیام های خود
با استفاده از تکنیک TF-IDF پیام را به بردار تبدیل کنید. از مدل برای پیشبینی هرزنامه یا همزمان بودن پیام استفاده کنید، سپس آن پیشبینی را روی صفحه نمایش دهید.
print('Predicting...')
message = ["You won 10000 dollars, please provide your account
details,So that we can transfer the money"]
message_vector = tf.transform(message)
category = model.predict(message_vector)
print("The message is", "spam" if category == 1 else "not spam")
پیام را با پیام خود جایگزین کنید.
خروجی به صورت زیر است:
این مدل میتواند پیامهای دیده نشده جدید را بهعنوان هرزنامه یا ham طبقهبندی کند.
چالش های پیش روی طبقه بندی هرزنامه ها در برنامه ها
چالش اصلی طبقهبندی هرزنامهها در برنامهها، طبقهبندی اشتباه پیامها است. مدلهای یادگیری ماشین همیشه درست نیستند. آنها ممکن است هرزنامه را به عنوان ham و بالعکس طبقه بندی کنند. در مورد طبقه بندی هام به عنوان هرزنامه، یک برنامه ممکن است ایمیل را از صندوق ورودی کاربر حذف کند و باعث شود پیام های مهم را از دست بدهد.