گفتم برای شروع، یه مقدمهای بگم در مورد اینکه چرا چنین مقالهای رو منتشر میکنم. این مقاله حاصل یک ارائه دانشگاه هست و از اونجایی که دوست دارم اطلاعاتی که بهدست میارم رو به اشتراک بزارم، گفتم در اینجا منتشر کنم. پس ارائهای در حد آشنا شدن با این کتابخونه هست و یک مقدار آموزش یک مدل فارسی رو در آخر میگم. بخش پایانی این مقاله یا همون آموزش یک مدل، شاید بشه گفت بهترین بخش این مقاله هست. نحوه آموزش مدل فارسی در مقالهای در مدیوم موجود هست اما با بررسیای که کردم، نیاز بود مقداری منظمتر و به زبان فارسی، نوشته بشه.
خب اسپیسی چیه؟ اگر در حوزه پردازش زبان طبیعی کار کرده باشیم احتمال داره در موردش اطلاعات داشته باشیم و یا شاید با کتابخونهای مثل NLTK کار کرده باشیم. اسپیسی هم یه کتابخونهای هست برای پردازش زبان طبیعی با زبان پایتون.
اسپیسی خودش رو پردازش زبان طبیعی با قدرت صنعتی معرفی میکند. و در مورد سه ویژگی صحبت میکند.
نصب اسپیسی:
از طریق بخش نصب سایت خود این کتابخانه، میتونید کانفیگ مخصوص خودتون رو پیدا کنید و نصبش کنید.
کانفیگ پیشفرض برای نصب به صورت زیر هست.
pip install -U pip setuptools wheel
pip install -U spacy
این دو خط بالا برای اجرای پیشنیاز و خود این کتابخونه هست.
python -m spacy download en_core_web_sm
اما یه بخش اصلی برای استفاده از این کتابخانه، استفاده از یک مدل آموزش داده شده هست. برای دانلود این مدل، باید مدل مورد نظرمون رو دانلود کنیم.
در توضیحات کتابخونه بهمون میگه من از خیلی از زبانها از جمله فارسی پشتیبانی میکنم. اما در بخش مدلها، مدلی برای زبان فارسی وجود نداره.
حالا اگر بخواهیم از مدل زبانهای موجود استفاده کنیم، باید بدونیم معنی دستور en_core_web_sm چی هست.
در اسپیسی، اطلاعتمون تبدیل به یک داکیومنتی میشه با آبجکت هایی به نام توکن. یعنی ما لیستی از
توکنهارو خواهیم داشت که این توکن ها در خود اطلاعات خیلی زیادی برامون دارند.
بارگزاری مدل آموزش دیده شده:
برای اینکه با این کتابخونه شروع به کار کنیم، باید مدل خودمون رو بارگزاری کنیم و داکیومنت رو به مدل بدیم. برای این کار از کد زیر استفاده میکنیم.
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
POS(Part-of-speech tagging)
میخواهیم جایگاه هر کلمه رو در جمله بدونیم.
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
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( استاپ ورد است یا خیر)
برخی از برچسبهای وابستگی رایج عبارتند از:
spacy.displacy.serve(doc, style="dep")
با دستور بالا میتونیم به صورت گرافیکی وابستگیهای بین کلمات و جایگاهشون رو مشاهده کنیم.
Morphology
مورفولوژی به تجزیه و تحلیل ساختار کلمات و شناسایی اجزای تشکیل دهنده آنها مانند ریشه، پیشوند و پسوند اشاره داره. این قابلیت به شما امکان میدهد تا اطلاعات زبانی عمیقتری را از متن استخراج کنید.
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("I was reading the paper .")
token = doc[0] # 'I'
print(token)
print(token.morph) # 'Case=Nom|Number=Sing|Person=1|PronType=Prs'
همونطور که مشخص هست، من اطلاعات توکن اول که در مورد I هست رو پرینت گرفتم که به عنوان مثال، این توکن در مورد اول شخص مفرد است.
Lemmatization
برای ریشه یابی کلمات، میتونیم از سه روش استفاده کنیم.
EditTreeLemmatizer): که براساس یک مدل آموزش دیده ریشه کلمات را پیدا میکند.
با استفاده از ریپازیتوری موجود در گیتهاب، میتونید ریشهیاب های مختلف رو مشاهده کنید و توسعه بدید.
با استفاده از این ویژگی، میتونید موجودیت آماری موجود در متن رو تشخیص بدید. به عنوان مثال وقتی در یک جملهای نام یک فرد آمده است، این کتابخانه میتواند مشخص کند که آن بخش، نام یک فرد است.
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
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
برخی از برچسبهای موجودیت پیشفرض:
آموزش مدل:
شاید یک بخش اصلی در این مقاله، آموزش یک مدل ساده باشه. در این بخش میخوام یک مدل ساده به زبان فارسی رو آموزش بدیم و 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("fa")
db = DocBin()
import json
f = open("annotations.json")
TRAIN_DATA = json.load(f)
for text, annot in tqdm(TRAIN_DATA["annotations"]):
doc = nlp.make_doc(text)
ents = []
for start, end, label in annot["entities"]:
span = doc.char_span(start, end, label=label, alignment_mode="contract")
if span is None:
print("Skipping entity")
else:
ents.append(span)
doc.ents = ents
db.add(doc)
db.to_disk("./dev.spacy")
بعد از ساخت داده های تست و ترین،حالا میتونیم مدل خودمون رو با دستور زیر با استفاده از داده ها بسازیم.
python -m spacy train config.cfg --output ./output --paths.train ./train.spacy --paths.dev ./dev.spacy
بعد از اجرای دستور، مدل ما در پوشهای به نام output ساخته خواهد شد و میتوانیم به صورت زیر از آن استفاده کنیم.
import spacy
nlp_ner = spacy.load("output/model-best")
doc = nlp_ner("متن مورد نظر")
for ent in doc.ents:
print(ent.text, ent.start_char, ent.end_char, ent.label_)
در آخر:
امیدوارم که به عنوان یک مقاله ابتدایی، مناسب باشه برای دوستانی که میخوان از این کتابخونه استفاده کنند.
یکی از مراجعی که برای آموزش مدل ازش استفاده کردم، نوشته آقای مجید پاکدل در مدیوم به این آدرس هست.
ممنونم از توجهتون.