محمدرضا برجیان
محمدرضا برجیان
خواندن ۷ دقیقه·۷ ماه پیش

پردازش زبان طبیعی با spacy

مقدمه:

گفتم برای شروع، یه مقدمه‌ای بگم در مورد اینکه چرا چنین مقاله‌ای رو منتشر می‌کنم. این مقاله حاصل یک ارائه دانشگاه هست و از اونجایی که دوست دارم اطلاعاتی که به‌دست میارم رو به اشتراک بزارم، گفتم در اینجا منتشر کنم. پس ارائه‌ای در حد آشنا شدن با این کتابخونه هست و یک مقدار آموزش یک مدل فارسی رو در آخر میگم. بخش پایانی این مقاله یا همون آموزش یک مدل، شاید بشه گفت بهترین بخش این مقاله هست. نحوه آموزش مدل فارسی در مقاله‌ای در مدیوم موجود هست اما با بررسی‌ای که کردم، نیاز بود مقداری منظم‌تر و به زبان فارسی، نوشته بشه.

خب اسپیسی چیه؟ اگر در حوزه پردازش زبان طبیعی کار کرده باشیم احتمال داره در موردش اطلاعات داشته باشیم و یا شاید با کتابخونه‌ای مثل NLTK کار کرده باشیم. اسپیسی هم یه کتابخونه‌ای هست برای پردازش زبان طبیعی با زبان پایتون.

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

  • صرفه جویی در زمان و ساخت پروداکت واقعی(‌دیگه مشخصه داره حدودا میگه من واسه ساخت یه محصول خوبم :)‌ )
  • اجرای سریع همراه با مدیریت حافظه چون از cython استفاده می‌کند.
  • کامیونیتی قوی چون از سال ۲۰۱۵ فعال هستند.( منظورم همونه که تو این مدت هر سوالی نیاز باشه پرسیده بشه، پرسیده شده و شما می‌تونید به جوابتون برسید یا می‌تونید از ساخته‌هایی که وجود داره استفاده کنید)

نصب اسپیسی:

از طریق بخش نصب سایت خود این کتابخانه، میتونید کانفیگ مخصوص خودتون رو پیدا کنید و نصبش کنید.
کانفیگ پیش‌فرض برای نصب به صورت زیر هست.

pip install -U pip setuptools wheel
pip install -U spacy

این دو خط بالا برای اجرای پیش‌نیاز و خود این کتابخونه هست.

python -m spacy download en_core_web_sm

اما یه بخش اصلی برای استفاده از این کتابخانه، استفاده از یک مدل آموزش داده شده‌ هست. برای دانلود این مدل، باید مدل مورد نظرمون رو دانلود کنیم.

در توضیحات کتابخونه بهمون میگه من از خیلی از زبان‌ها از جمله فارسی پشتیبانی می‌کنم. اما در بخش مدل‌ها، مدلی برای زبان فارسی وجود نداره.

حالا اگر بخواهیم از مدل زبان‌های موجود استفاده کنیم، باید بدونیم معنی دستور en_core_web_sm چی هست.

  • دو حرف اول آن یعنی en به معنای زبان هست( در اینجا زبان انگلیسی)
  • بخش بعدی یعنی core یعنی مدلی که تمام ویژگی های مختلف مثل ریشه‌یابی، شناسایی موجودیت‌های نامگذاری شده و... را داشته باشد. ما به جای core از dep هم می‌توانیم استفاده کنیم که شناسایی موجودیت‌های نامگذاری شده را پشتیبانی نمی‌کند.
  • بخش سوم یعنی web به این معنی هست که مدلی می‌خواهیم که در محیط وب آموزش داده شده است. میتوانیم از news به جای آن استفاده کنیم یعنی مدل آموزش داده شده با اخبار.
  • در آخر سایز مدل و نوع وکتورایز هست که میتونه sm (small), md (medium), lg (large) or trf (transformer) باشه.

در اسپیسی، اطلاعتمون تبدیل به یک داکیومنتی میشه با آبجکت هایی به نام توکن. یعنی ما لیستی از
توکن‌هارو خواهیم داشت که این توکن ها در خود اطلاعات خیلی زیادی برامون دارند.

بارگزاری مدل آموزش دیده شده:

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

import spacy
nlp = spacy.load(&quoten_core_web_sm&quot)
doc = nlp(&quotApple is looking at buying U.K. startup for $1 billion&quot)


شرح برخی از ویژگی‌‌های وابستگی های زبانی:

POS(Part-of-speech tagging)

میخواهیم جایگاه هر کلمه رو در جمله بدونیم.


import spacy
nlp = spacy.load(&quoten_core_web_sm&quot)
doc = nlp(&quotApple is looking at buying U.K. startup for $1 billion&quot)
for token in doc:
print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
token.shape_, token.is_alpha, token.is_stop)

با استفاده از کد بالا، هر توکن موجود در جمله‌ای که داشتیم رو با یک حلقه بررسی کردیم و ویژگی هایی که نیاز داشتیم رو چاپ کردیم.

در متغیر توکن: text (کلمه)، lemma_(ریشه کلمه)، pos_( جایگاه کلمه از نظر معنایی)، tag_( اطلاعات دقیق تر در مورد جایگاه کلمه)، dep_(ارتباط بین توکین‌ها)،shape_( شکل کلمه حروف بزرگ، نقطه گذاری، اعداد)، alpha_( حرف هست یا خیر)، is_stop( استاپ ورد است یا خیر)
برخی از برچسب‌های وابستگی رایج عبارتند از:

  • nsubj: اسم فاعل
  • dobj: مفعول مستقیم
  • obj: مفعول
  • aux: فعل کمکی
  • prep: پیش‌نهاد
  • pobj: مفعول پیش‌نهاد
  • mod: صفت
  • advmod: قید
  • compound: ترکیب
spacy.displacy.serve(doc, style=&quotdep&quot)

با دستور بالا می‌تونیم به صورت گرافیکی وابستگی‌های بین کلمات و جایگاهشون رو مشاهده کنیم.


Morphology

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

import spacy
nlp = spacy.load(&quoten_core_web_sm&quot)
doc = nlp(&quotI was reading the paper .&quot)
token = doc[0] # 'I'
print(token)
print(token.morph) # 'Case=Nom|Number=Sing|Person=1|PronType=Prs'

همونطور که مشخص هست، من اطلاعات توکن اول که در مورد I هست رو پرینت گرفتم که به عنوان مثال، این توکن در مورد اول شخص مفرد است.


Lemmatization

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

  • بر اساس قوانین( rule-based ): که همونطوری که از اسمش مشخص هست،‌بر اساس یکیسری قانون، ریشه کلمات رو پیدا می‌کند.
  • جستجو(lookup): که براساس چیزی شبیه دیکشنری، ریشه کلمات را پیدا می‌کند.
  • مدل آموزش دیده(EditTreeLemmatizer): که براساس یک مدل آموزش دیده ریشه کلمات را پیدا می‌کند.

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


Named Entity Recognition

با استفاده از این ویژگی، میتونید موجودیت آماری موجود در متن رو تشخیص بدید. به عنوان مثال وقتی در یک جمله‌ای نام یک فرد آمده است، این کتابخانه می‌تواند مشخص کند که آن بخش، نام یک فرد است.

import spacy
nlp = spacy.load(&quoten_core_web_sm&quot)
doc = nlp(&quotApple is looking at buying U.K. startup for $1 billion&quot)
for ent in doc.ents:
print(ent.text, ent.start_char, ent.end_char, ent.label_)

با توجه به مثال بالا، خروجی پایین رو خواهیم داشت.

Apple 0 5 ORG
U.K. 27 31 GPE
$1 billion 44 54 MONEY

برخی از برچسب‌های موجودیت پیش‌فرض:

  • PERSON: نام افراد (مانند "باراک اوباما"، "مریم میرزاخانی")
  • ORG: نام سازمان‌ها (مانند "گوگل"، "دانشگاه صنعتی شریف")
  • GPE: نام مکان‌های جغرافیایی (مانند "ایران"، "پاریس")
  • DATE: تاریخ (مانند "14 ژانویه 2024"، "1399-12-29")
  • TIME: زمان (مانند "10:30 صبح"، "ساعت 2 بعد از ظهر")
  • MONEY: واحدهای پولی (مانند "دلار"، "یورو")
  • PRODUCT: نام محصولات (مانند "آیفون 14"، "لپ تاپ دل")
  • EVENT: نام رویدادها (مانند "جام جهانی فوتبال"، "جشنواره فیلم کن")
  • NORP: نام گروه‌های مذهبی، قومی و سیاسی (مانند "مسلمانان"، "دموکرات‌ها")


آموزش مدل:

شاید یک بخش اصلی در این مقاله، آموزش یک مدل ساده باشه. در این بخش میخوام یک مدل ساده به زبان فارسی رو آموزش بدیم و named entity برای خودمون درست کنیم.

خب در مرحله اول نیاز هست که یک متنی داشته باشیم که تگ گذاری کنیم. این متن رو آماده می‌کنیم و وارد این سایت میشیم تا بتونیم کلمات خودمون رو تگ گذاری کنیم. وقتی متن ما لود شد، از تگ جدید می‌تونیم تگ خودمون رو بسازیم و سپس با کلیک روی یک کلمه، آن کلمه رو تگ گذاری کنیم. بعد از تگ گذاری، روی دکمه ذخیره کلیک میکنیم سپس از بخش انوتیشن، بر روی export کلیک می‌کنیم. با این کار یک فایل انوتیشن دانلود می‌شود.

در مرحله بعد فایل کانفیگ زبان را از سایت اسپایسی می‌توانیم دریافت کنیم.( در این بخش، فیچرهای مورد نظر را علامت می‌زنیم و با کلیک بر روی دانلود، فایل دانلود را دریافت می‌کنیم.

python -m spacy init fill-config base_config.cfg config.cfg

سپس با دستور بالا، کانفیگ های باقیمانده فایل خود را تکمیل می‌کنیم.

ساخت train,test مدل:

import spacy
from spacy.tokens import DocBin
from tqdm import tqdm
nlp = spacy.blank(&quotfa&quot)
db = DocBin()
import json
f = open(&quotannotations.json&quot)
TRAIN_DATA = json.load(f)
for text, annot in tqdm(TRAIN_DATA[&quotannotations&quot]):
doc = nlp.make_doc(text)
ents = []
for start, end, label in annot[&quotentities&quot]:
span = doc.char_span(start, end, label=label, alignment_mode=&quotcontract&quot)
if span is None:
print(&quotSkipping entity&quot)
else:
ents.append(span)
doc.ents = ents
db.add(doc)
db.to_disk(&quot./dev.spacy&quot)
  • برای تست و ترین کردن یک مدل، نیاز به داده ای برای ترین و داده ای برای تست داریم. من برای مثال در این بخش، هر دو داده را از یک فایل استفاده کرده ام. این فایل همان فایل جیسون انوتیشنی است که در مرحله قبل دریافت کردم. پس دستور بالا را یک بار برای تست اجرا میکنم و نام داده ذخیره شده در دیسک را dev.spacy و بار دیگر نام آن را train.spacy می‌گذارم.
  • بعد از هر بار اجرا، یک فایل با نام های گفته شده برای من ذخیره می‌شود.

بعد از ساخت داده های تست و ترین،حالا میتونیم مدل خودمون رو با دستور زیر با استفاده از داده ها بسازیم.

python -m spacy train config.cfg --output ./output --paths.train ./train.spacy --paths.dev ./dev.spacy

بعد از اجرای دستور، مدل ما در پوشه‌ای به نام output ساخته خواهد شد و میتوانیم به صورت زیر از آن استفاده کنیم.

import spacy
nlp_ner = spacy.load(&quotoutput/model-best&quot)
doc = nlp_ner(&quotمتن مورد نظر&quot)
for ent in doc.ents:
print(ent.text, ent.start_char, ent.end_char, ent.label_)

در آخر:

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

یکی از مراجعی که برای آموزش مدل ازش استفاده کردم، نوشته آقای مجید پاکدل در مدیوم به این آدرس هست.

ممنونم از توجهتون.

nlpپردازش زبان طبیعی
فقط یک برنامه نویس اندروید...
شاید از این پست‌ها خوشتان بیاید