فهرست مطالب
- کلمات مفرد (Singular) و جمع (Plural): language و languages، word و words
- اسم مصدر (Gerunds یا Present Participles): giving، parsing و learning
- قیدها (Adverbs): قیدها اغلب به ly ختم میشوند. مانند bad:badly، rough:roughly
- وجه وصفی فعل (Participle): given و taken
ریشهیابی فرایند شناسایی و یکسانسازی کلمات معادل با شکل و فرمهای مختلف است.
اما شاید بپرسید که چرا برای هر کلمه معنادار در متن، باید یکشکل یا یک فرم از آن را داشته باشیم؟
پاسخ: اگر برای کلمات با شکل و فرمهای مختلف، تنها یکشکل یا فرم به دست آوریم (ریشه آنها را داشته باشیم)، فراوانی تعداد تکرار هر کلمه در متن افزایشیافته، اندازه تعداد واژگان کل متن کاهش پیدا کرده و همه اینها باعث میشوند که مصورسازی (Visualization)، دستهبندی (Classification) و تجزیهوتحلیل (Analysis) بهتری داشته باشیم.
دو روش رایج برای بهدستآوردن ریشه کلمات معادل با شکلها و فرمهای مختلف Stemming و Lemmatization است.
دوست دارید پروژههایی برای پردازش متن یاد بگیرید که در کارهای دنیای واقعی استفاده میشوند؟ صفحه آموزش متن کاوی فارسی با شبکههای عصبی را ببینید.
Stemming (حذف پسوند (Suffix) یک کلمه)
به فرایند حذف پسوند کلمات stemming گفته میشود. برای مثال، اگر سه کلمه lightning, lightly و lighting را داشته باشیم، کلمه light بهعنوان ریشه فرض شده و پسوندهای آنها یعنی ning, ly, ing را که به انتهای light اضافه شدهاند، حذف میشوند.
البته ممکن است که کلمات، پیشوند (Prefix) داشته باشند یا اینکه همزمان پیشوند و پسوند داشته باشند اما stemming فقط پسوندها را حذف میکند که البته این کار را هم به شکل سختگیرانهای انجام میدهد.
به دو مثال change و study دقت کنید. در stemming، ریشه آنها یعنی “chang” و “studi” را نگه داشته و هرآنچه را که بهعنوان پسوند در انتهای کلمات داریم، حذف میکنیم.
کتابخانه NLTK در پایتون، stemmers بسیار و متنوعی مانند standardPorterStemmer را ارائه میدهد. میتوانید لیست سایر stemmers را در صفحه nltk.stem package پیدا کنید. یکی از مزایای stemmers سریع بودن آنهاست. شما میتوانید ریشه میلیونها کلمه را به کمک سیستم یا رایانه شخصی خودتان، تنها در عرض چند ثانیه به دست آورید.
from nltk.tokenize import WordPunctTokenizer
from nltk.stem import PorterStemmer
from nltk.corpus import stopwords
# Get the text, for instance from Wikipedia.
# see chap 1 for the wikipedia_page function
text = wikipedia_page('Earth').lower()
# Tokenize and remove stopwords
tokens = WordPunctTokenizer().tokenize(text)
tokens = [tk for tk in tokens if tk not in stopwords.words('english')]
# Instantiate a stemmer
ps = PorterStemmer()
# and stem
stems = [ps.stem(tk) for tk in tokens ]
میتوانیم 10 ریشه (stem) بهدستآمده را بهصورت تصادفی انتخاب کنیم. بهاینترتیب اگر کد زیر را سه بار اجرا کنیم:
import numpy as np
np.random.choice(stems, size = 10)
این نتایج را خواهیم داشت (اگر شما این کد را اجرا کنید، بهاحتمال زیاد نتایج متفاوتی میبینید زیرا با هر بار اجرا، 10 کلمه بهصورت کاملاً رندوم انتخاب میشوند):
> ['subtrop', 'dure', 'electr', 'eurasian', 'univers', 'cover', 'between','from', 'that', 'earth']
> ['in', 'interior', 'roughli', 'holocen', 'veloc', 'impact', 'in', 'point', 'the', 'come']
> ['caus', 'proxim', 'migrat', 'lithospher', 'as', 'on', 'are', 'earth', 'low', 'also']
برای اطلاعات بیشتر در مورد مزایا و معایب stemming، میتوانید مقاله Devopedia به نام Stemming را بررسی کنید.
Stemming روش کاملی نیست؛ زیرا بهدستآوردن ریشه ناقص بعضی از کلمات مانند electr عملاً کمکی به ما نمیکند؛ بنابراین میتوانیم از یک روش مناسبتر دیگری به نام lemmatization استفاده کنیم.
برای آشنایی کامل و پروژه محور با مفاهیم پردازش زبان طبیعی دوره آموزش پردازش زبان طبیعی مقدماتی را ببینید.
Lemmatization چیست؟
به شکل اصلی یک کلمه که میتوان آن را در دیکشنری جستجو کرد، lemma میگویند؛ بنابراین شکل اصلی کلمه universities، کلمه university و شکل اصلی کلمه universe، نیز همان universe است. درواقع در lemmatization ریشه ناقص و یا غیرقابلتفسیر به دست نمیآید، پس یا برای یک توکن ریشه نخواهیم داشت یا ریشه صحیح و دقیق خواهد بود.
به lemma، شکل استاندارد کلمه (canonical form of a word)، نیز گفته میشود.
lemmatization فرایند بهدستآوردن شکل استاندارد و lemma چند کلمه است که باعث میشود کلمه بهدستآمده خواناتر، تفسیر پذیرتر و در مقایسه با stemming درستتر و البته کندتر باشد.
فرایند Lemmatization برای کلمات studying، studies و study
یک ریشهیاب (lemmatizer) نهتنها مناسبترین و مهمترین شکل اصلی یک کلمه را پیدا میکند، بلکه نقش دستوری آن کلمه در جمله را بررسی میکند تا شکل متعارف آن را به دست آورد.
Lemmatization بر اساس کل جمله
به کلمه meeting در دو جمله سمت چپ توجه کنید. اگر کلمه meeting نقش دستوری noun را داشته باشد (جمله اول)، بهصورت meeting، lemmatize شده و اگر نقش دستوری verb را داشته باشد (جمله دوم)، بهصورت meet، lemmatize میشود و در هر دو جمله فعلهای was و were به شکل to be خود lemmatize شدهاند.
فرایند Lemmatization، وابسته به زبان (language-dependent) است. کتابخانههای بزرگ و مهم NLP، قابلیت lemmatize کردن را برای متداولترین زبانهای هندی و اروپایی مانند فرانسوی، اسپانیایی و آلمانی را به ما ارائه میدهند، اما ممکن است پیداکردن یک کتابخانه و ابزار خوب برای زبانهایی مانند پارسی، عربی و روسی دشوارتر باشد.
کتابخانه NLTK یک lemmatizer مبتنی بر WordNet دارد که یک پایگاهداده واژگانی (lexical database) گسترده برای زبان انگلیسی است. میتوانید این پایگاهداده را در صفحه nltk.stem package documentation بررسی کنید. هر چند انتخاب شخصی ما، lemmatizer کتابخانه spacy.io است.
Tokenize کردن و Lemmatize کردن با استفاده از کتابخانه SpaCy
کتابخانه spaCy یکی از ضروریترین ابزارها برای همه افرادی است که در حوزه NLP و روی متون انگلیسی کار میکنند. با استفاده از این کتابخانه، علاوه بر انجام دادن تسکهای پایهای همچون tokenization، ریشهیابی lemmatization و part-of-speech (POS) tagging، میتوانیم تشخیص موجودیت های اسمی (named entity recognition (NER)) و تکنیکهای embeddings را برای دهها زبان پیادهسازی کنیم.
- Embeddings یک نمایش برداری از کلمات با ویژگیهای مشابه هستند که در مقاله word embedding چیست، آنها را بررسی خواهیم کرد.
- Part-of-speech tagging (POS) شامل تشخیص نقش دستوری کلمات در جمله مانند noun، verb و adjective میشود.
- با استفاده از Named-entity recognition (NER)، اطلاعات مهمی مانند اسم افراد، مکانها و سازمانهای بهکار رفته در متن شناسایی میشود.
میتوانید کتابخانه spaCy را با conda یا pip نصب کنید. پس از نصب کتابخانه باید مدلی را که نیاز دارید، دانلود کنید. مدلهای کتابخانه spaCy وابسته به زبان (language-dependent) هستند و اندازه آنها متفاوت است. دستورالعملهای ذکر شده در صفحه install را دنبال کنید و مدل ساده و سبک تر مخصوص زبان انگلیسی به نام en_core_web_sm را دانلود کنید.
استفاده از کتابخانه spaCy در یک متن به زبان پایتون، شامل سهگام است:
- import spaCy
- load کردن مدل با دستور nlp = spacy.load(“en_core_web_sm”)
- اجرای مدل بر روی متن موردنظر: doc = nlp(“This is a sentence.”)
در واقع مدل nlp منبع جادویی ماست و doc که بهصورت object تعریف شده شامل اطلاعات استنتاج شده توسط کتابخانه spaCy بوده که البته این اطلاعات به کمک مدل nlp به دست آمدهاند. دقت کنید که doc یک iterable object است؛ یعنی میتوانیم روی آن حلقه (loop) بزنیم.
با اجرای مدل nlp بر روی یک متن، کتابخانه spaCy فرایند تجزیه (parsing) و تحلیل متن (text analysis) خود را پیادهسازی میکند.
Tokenize کردن با استفاده از کتابخانه SpaCy
کتابخانه spaCy توکنهای یک متن را مستقیماً بدون مشخصکردن tokenizer و یا تعریف دقیق tokenization، به دست میآورد:
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("Roads? Where we’re going we don’t need roads!")
for token in doc:
print(token)
با اجرای کد بالا، لیست توکنهای زیر ایجاد میشود:
[Roads, ?, Where, we, ’re, going, we, do, n’t, need, roads, !]
باتوجهبه لیست میبینیم که در فرایند tokenization، علائم نگارشی (punctuation) بهدرستی تشخیص داده شدهاند؛ حتی میتوانیم اطلاعات اضافهتری به دست آوریم!
هر المان از doc object، اطلاعاتی در مورد ماهیت و سبک توکن دارد:
- is_space: بهصورت True و False مشخص میکند که آیا توکن white space است.
- is_punct: بهصورت True و False مشخص میکند که آیا توکن یک punctuation است.
- is_upper: بهصورت True و False مشخص میکند که آیا همه حرفهای بهکاررفته در توکن، حرفهای بزرگ انگلیسی است.
- is_digit: بهصورت True و False مشخص میکند که آیا توکن یک عدد است.
- is_stop: بهصورت True و False مشخص میکند که آیا توکن یک ایست واژه (Stop Word) است.
میتوانیم در کد زیر آنها را تست کنیم:
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("All aboard! \t Train NXH123 departs from platform 22 at 3:16 sharp.")
for token in doc:
print(token, token.is_space, token.is_punct, token.is_upper, token.is_digit)
بنابراین خروجی زیر را خواهیم داشت:
token space? punct? upper? digit?
All False False False False
aboard False False False False
! False True False False
True False False False
Train False False False False
NXH123 False False True False
departs False False False False
from False False False False
platform False False False False
22 False False False True
at False False False False
3:16 False False False False
sharp False False False False
! False True False False
دقت کنید که:
- خروجی تابع is_space برای المان <tab> مقدار True است.
- خروجی تابع is_upper برای المان NXH123، نیز True است.
- سایر المانها مانند عدد و punctuation نیز بهدرستی تشخیص داده شدهاند.
Lemmatize کردن با استفاده از کتابخانه SpaCy
برای مدیریت فرایند lemmatization با استفاده از کتابخانه spaCy، از token.lemma_ استفاده میکنیم:
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("I came in and met with her teammates at the meeting.")
for token in doc:
print(f"{token.text}\t {token.lemma_} ")
بنابراین خروجی زیر را خواهیم داشت:
token lemma
--------------------
I -PRON-
came come
in in
and and
met meet
with with
her -PRON-
teammates teammate
at at
the the
meeting meeting
. .
همانطور که میبینید کتابخانه spaCy، فعلها و کلمات جمع را بهدرستی lemmatize کرده است. برای دو توکن I و her نتیجه lamma به دست نیاورده و در عوض آنها را بهعنوان ضمیر بهصورت “-PRON-” مشخص کرده است.
هنوز تمرین کدهای پردازش زبان طبیعی را شروع نکردید، چون برنامهنویسی بلد نیستید؟ اصلا نگران نباشید. دوره آموزش پایتون ویژه هوش مصنوعی را در کانال یوتیوب دیتاهاب ببینید.
- کلمات به شکلها و فرمهای مختلفی وجود دارند و ما با پیداکردن یک فرم مشترک یعنی ریشه آنها، میتوانیم اندازه تعداد واژگان دیتاست را کاهش دهیم.
- در stemming برای بهدستآوردن ریشه هر کلمه، پسوند انتهایی کلمه حذف میشود. این کار یا سرعت بالایی انجام میشود اما گاهی اوقات باعث شده که تفسیر نتایج سخت باشد.
- Lemmatization در مقایسه با Stemming روشی هوشمندانهتر است زیرا معنی کلمه را در نظر میگیرد.
- در جواب spaCy چیست میتوان گفت از کتابخانه spaCy برای کار با مدلهای وابسته به زبان، با اندازهها و پیچیدگیهای مختلف استفاده میشود.
- برای مدیریت پیشرفتهتر و نامحدود tokenization از کتابخانه spaCy استفاده میکنیم، زیرا قابلیتهای مختلفی دارد.
- میتوانید کدهای مربوط به این مقاله را در این Jupyter Notebook پیدا کنید.
حال که فهمیدیم spaCy چیست، در قسمت بعدی با مقاله آموزش regex، به استخراج اطلاعات (information extraction) میپردازیم و خواهیم دید که چگونه عناصر متنی خاص مانند ایمیلها، hashtagها و URLها را بر اساس الگوهای تکراریشان شناسایی کنیم.