spacy چیست؟ پیش پردازش متن در پایتون با کتابخانه spacy

کتابخانه spacy چیست

فهرست مطالب

وجود کلمات معادل با شکل و فرم‌های مختلف در مقاله‌های قبلی، متن مقاله ویکی‌پدیا با موضوع Earth را دانلود کردیم، توکن‌های آن را به دست آورده و ایست‌واژه‌های (Stop Words) متن اصلی را حذف کردیم تا خروجی ابر کلمات درست‌تر و بهتری داشته باشیم. سپس مفهوم توکن‌سازی را عمیق‌تر بررسی کردیم و کتابخانه NLTK را برای پیش‌پردازش داده‌های متنی استفاده کردیم. در این مقاله با کتابخانه spaCy کار تمیزکردن داده متنی را ادامه می‌دهیم. موضوع این است که کلمات می‌توانند به شکل‌های مختلفی در یک متن وجود داشته باشند. به‌عنوان‌مثال، فعل to be به شکل‌های متفاوت is، am، are، was و … در یک متن ظاهر می‌شود. هرچند همه این‌ها مصدر فعل (verb’s infinitive) یکسانی دارند، اما به‌عنوان فعل‌های مجزا از هم در نظر گرفته می‌شوند. البته که مجزا درنظرگرفتن آن‌ها کار درستی نیست و باید آن را مدیریت کرد. علاوه بر صرف مختلف فعل‌ها، کلمات دیگری نیز وجود دارند که به شکل‌های مختلف ظاهر می‌شوند:
  • کلمات مفرد (Singular) و جمع (Plural): language و languages، word و words
  • اسم مصدر (Gerunds یا Present Participles): giving، parsing و learning
  • قیدها (Adverbs): قیدها اغلب به ly ختم می‌شوند. مانند bad:badly، rough:roughly
  • وجه وصفی فعل (Participle): given و taken
ریشه یابی کلمات با اضافه‌شدن پسوندهای مختلف به ریشه یک کلمه مانند light، شکل‌ها و فرم‌های مختلفی از آن (light) ایجاد می‌شود. پس در ادامه تعریف ساده‌ای از ریشه‌یابی داشته باشیم:

ریشه‌یابی فرایند شناسایی و یکسان‌سازی کلمات معادل با شکل و فرم‌های مختلف است.

اما شاید بپرسید که چرا برای هر کلمه معنادار در متن، باید یک‌شکل یا یک فرم از آن را داشته باشیم؟

پاسخ: اگر برای کلمات با شکل و فرم‌های مختلف، تنها یک‌شکل یا فرم به دست آوریم (ریشه آن‌ها را داشته باشیم)، فراوانی تعداد تکرار هر کلمه در متن افزایش‌یافته، اندازه تعداد واژگان کل متن کاهش پیدا کرده و همه این‌ها باعث می‌شوند که مصورسازی (Visualization)، دسته‌بندی (Classification) و تجزیه‌وتحلیل (Analysis) بهتری داشته باشیم.

دو روش رایج برای به‌دست‌آوردن ریشه کلمات معادل با شکل‌ها و فرم‌های مختلف Stemming و Lemmatization است.

دوست دارید پروژه‌هایی برای پردازش متن یاد بگیرید که در کارهای دنیای واقعی استفاده می‌شوند؟ صفحه آموزش متن کاوی فارسی با شبکه‌های عصبی را ببینید.

Stemming (حذف پسوند (Suffix) یک کلمه)

به فرایند حذف پسوند کلمات stemming گفته می‌شود. برای مثال، اگر سه کلمه lightning, lightly و lighting را داشته باشیم، کلمه light به‌عنوان ریشه فرض شده و پسوندهای آن‌ها یعنی ning, ly, ing را که به انتهای light اضافه شده‌اند، حذف می‌شوند.

البته ممکن است که کلمات، پیشوند (Prefix) داشته باشند یا اینکه هم‌زمان پیشوند و پسوند داشته باشند اما stemming فقط پسوندها را حذف می‌کند که البته این کار را هم به شکل سخت‌گیرانه‌ای انجام می‌دهد.

به دو مثال change و study دقت کنید. در stemming، ریشه آن‌ها یعنی “chang” و “studi” را نگه داشته و هرآنچه را که به‌عنوان پسوند در انتهای کلمات داریم، حذف می‌کنیم.مثال‌هایی از stemming

کتابخانه NLTK در پایتون، stemmers بسیار و متنوعی مانند standardPorterStemmer را ارائه می‌دهد. می‌توانید لیست سایر stemmers را در صفحه nltk.stem package پیدا کنید. یکی از مزایای stemmers سریع بودن آن‌هاست. شما می‌توانید ریشه میلیون‌ها کلمه را به کمک سیستم یا رایانه شخصی خودتان، تنها در عرض چند ثانیه به دست آورید.

حال لازم است که دست به کد شویم و stemming را بر روی مقاله ویکی‌پدیا با موضوع Earth (که در مقاله‌های قبل آن را بررسی کردیم)، پیاده‌سازی کنیم. ابتدا متن مقاله را tokenize کرده و سپس ریشه هر توکن را به دست می‌آوریم:
				
					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']

				
			
بر اساس نتایج به‌دست‌آمده، علاوه بر داشتن کلمات کاملی مانند earth، low و point، کلمات و ریشه‌های ناقصی مانند subtrop، electr، roughli، caus و proxim را نیز داریم. همان‌طور که در عکس مثال‌هایی از stemming مشخص است، stemming فرایندی یک‌طرفه است. فرض کنید که کلمه electr را به‌عنوان ریشه داشته باشیم و می‌خواهیم مشخص کنیم که کلمه اصلی پیش از فرایند stemming چه بوده است. متأسفانه جواب مشخصی نداریم، زیرا کلمه اصلی می‌تواند electronic، electrical، electricity و یا حتی electrons باشد. اگر کلمه univers را به‌عنوان ریشه به دست آوریم هم این مشکل را خواهیم داشت. کلمه اصلی universities بوده یا universe؟ عملاً پاسخ‌دادن به این سؤال ممکن نیست.

برای اطلاعات بیشتر در مورد مزایا و معایب stemming، می‌توانید مقاله Devopedia به نام Stemming را بررسی کنید.

Stemming روش کاملی نیست؛ زیرا به‌دست‌آوردن ریشه ناقص بعضی از کلمات مانند electr عملاً کمکی به ما نمی‌کند؛ بنابراین می‌توانیم از یک روش مناسب‌تر دیگری به نام lemmatization استفاده کنیم.

برای آشنایی کامل و پروژه محور با مفاهیم پردازش زبان طبیعی دوره آموزش پردازش زبان طبیعی مقدماتی را ببینید.

Lemmatization چیست؟

به شکل اصلی یک کلمه که می‌توان آن را در دیکشنری جستجو کرد، lemma می‌گویند؛ بنابراین شکل اصلی کلمه universities، کلمه university و شکل اصلی کلمه universe، نیز همان universe است. درواقع در lemmatization ریشه ناقص و یا غیرقابل‌تفسیر به دست نمی‌آید، پس یا برای یک توکن ریشه نخواهیم داشت یا ریشه صحیح و دقیق خواهد بود.

به lemma، شکل استاندارد کلمه (canonical form of a word)، نیز گفته می‌شود.

lemmatization فرایند به‌دست‌آوردن شکل استاندارد و lemma چند کلمه است که باعث می‌شود کلمه به‌دست‌آمده خواناتر، تفسیر پذیرتر و در مقایسه با stemming درست‌تر و البته کندتر باشد.

lemmatization example 01

فرایند Lemmatization برای کلمات studying، studies و study

یک ریشه‌یاب (lemmatizer) نه‌تنها مناسب‌ترین و مهم‌ترین شکل اصلی یک کلمه را پیدا می‌کند، بلکه نقش دستوری آن کلمه در جمله را بررسی می‌کند تا شکل متعارف آن را به دست آورد.

lemmatization example 02

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)، اطلاعات مهمی مانند اسم افراد، مکان‌ها و سازمان‌های به‌کار رفته در متن شناسایی می‌شود.
POS و NER مباحث پیشرفته‌تری هستند که در آخرین مقاله‌ی آموزشی به طور مختصر آن‌ها را بررسی می‌کنیم.

می‌توانید کتابخانه spaCy را با conda یا pip نصب کنید. پس از نصب کتابخانه باید مدلی را که نیاز دارید، دانلود کنید. مدل‌های کتابخانه spaCy وابسته به زبان (language-dependent) هستند و اندازه آن‌ها متفاوت است. دستورالعمل‌های ذکر شده در صفحه install را دنبال کنید و مدل ساده و سبک تر مخصوص زبان انگلیسی به نام en_core_web_sm را دانلود کنید.

استفاده از کتابخانه spaCy در یک متن به زبان پایتون، شامل سه‌گام است:

  1. import spaCy
  2. load کردن مدل با دستور nlp = spacy.load(“en_core_web_sm”)
  3. اجرای مدل بر روی متن موردنظر: 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
<tab>   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ها را بر اساس الگوهای تکراری‌شان شناسایی کنیم.

مطالب بیشتر

chatgpt چیست

چت بات ChatGPT چیست؟

فهرست مطالب اگه میخوای به ساده‌ترین شکل ممکن بفهمی ChatGPT چیه، جای درستی اومدی! امروز

دیدگاهتان را بنویسید