معرفی کلی پروژه
توکنایزر (Tokenizer) یکی از مراحل کلیدی در پردازش زبان طبیعی (NLP) هست. کارش اینه که متن رو به واحدهای کوچکتر مثل جمله، کلمه یا حتی زیرکلمه تقسیم کنه. برای متون فارسی این موضوع اهمیت ویژهای داره، چون:
-
فارسی فاصله مجازی (نیمفاصله) داره.
-
شکلهای مختلف یک کلمه (مثلاً "میروم" و "میروم") وجود داره.
-
علائم نگارشی و اعداد به شکلهای مختلف نوشته میشن.
-
پسوندها و پیشوندها به راحتی قابل جداسازی نیستند.
پروژهی ما ساخت یک توکنایزر اختصاصی برای متون فارسی هست که بشه توی کاربردهای واقعی مثل جستجو، ترجمه ماشینی، چتبات، خلاصهسازی متن یا تحلیل احساسات استفادهاش کرد.
مراحل کار
1. تعریف نیازمندیها
-
هدف: توکنایزر برای کلمات فارسی.
-
ورودی: متن خام فارسی (مقاله، توییت، متن کتاب و …).
-
خروجی: لیست توکنها (کلمات، علائم و ...).
-
سطح: میخواهیم هم به صورت ساده کار کنه (بر اساس فاصله و علائم)، هم در سطح پیشرفته (مدیریت نیمفاصله، جدا کردن پسوندها و …).
2. جمعآوری داده
برای تست و آموزش توکنایزر نیاز به متن فارسی داریم. چند منبع:
-
ویکیپدیای فارسی (کرول یا دیتاست آماده).
-
مقالات خبری (ایرنا، بیبیسی فارسی، ایسنا و …).
-
کتابهای عمومی فارسی.
3. نرمالسازی (Normalization)
قبل از توکنسازی باید متن رو یکدست کنیم. اینجا چند روش داریم:
-
روش ساده (Rule-based):
-
حذف حروف کشیده (سلاممم → سلام).
-
تبدیل کاراکترهای عربی به فارسی (ي → ی، ك → ک).
-
حذف علائم اضافی و ایموجیها در صورت نیاز.
-
-
ابزارهای آماده:
4. روشهای توکنسازی
الف) بر اساس قوانین (Rule-based)
-
شکستن متن با استفاده از فاصله (
split(" ")). -
تشخیص نیمفاصلهها (میروم ≠ میروم).
-
نگه داشتن علائم به صورت جداگانه.
مزایا: سریع و ساده.
معایب: دقت پایین در متون پیچیده.
ب) استفاده از ابزارهای آماده
-
Hazm → یک توکنایزر ساده و قابل اعتماد برای فارسی.
-
Parsivar → توکنایزر دقیقتر، مخصوصاً برای متون رسمی.
ج) مبتنی بر یادگیری ماشین (ML-based)
-
آموزش یک مدل برای پیشبینی محل جدایی توکنها.
-
ورودی: متن برچسبخورده (کجا کلمه تمام میشود).
-
روشها:
-
مدلهای BiLSTM + CRF.
-
مدلهای Transformer مثل BERT (بهویژه ParsBERT).
-
مزایا: دقت بالا.
معایب: نیازمند دیتاست بزرگ و محاسبات بیشتر.
د) زیرکلمهای (Subword Tokenization)
برای کاربردهای NLP مدرن (مثل ترجمه ماشینی و BERT) به جای کلمات کامل، از Subword Tokenization استفاده میکنیم:
-
Byte Pair Encoding (BPE).
-
SentencePiece (Unigram/BPE).
-
WordPiece (مثل BERT).
این روشها حتی کلمات ناشناخته رو هم به زیرکلمات میشکنن و در پردازش خیلی بهتر جواب میدن.
5. ارزیابی (Evaluation)
برای ارزیابی توکنایزر چند معیار داریم:
-
Precision, Recall, F1-score در تشخیص مرز کلمات.
-
مقایسه خروجی با دیتاست استاندارد (مثل PerDT).
6. استفاده در پروژه واقعی
بعد از ساخت توکنایزر میتونیم در کاربردهای زیر استفاده کنیم:
-
جستجوی متنی (مثلاً در موتور جستجو).
-
تحلیل احساسات (مثبت/منفی بودن یک متن).
-
ترجمه ماشینی.
-
چتبات فارسی.
شروع پروژه
# گام اول: نصب کتابخانههای مورد نیاز
# نصب hazm برای نرمالسازی و توکنسازی متون فارسی
# pip install hazm
from hazm import Normalizer, word_tokenize, SentenceTokenizer
# گام دوم: نرمالسازی متن
# نرمالسازی متن برای تبدیل حروف عربی به فارسی و حذف کاراکترهای غیرضروری
normalizer = Normalizer()
# یک متن نمونه به زبان فارسی
text = "سلام! من یک پروژه برای ساخت توکنایزر فارسی دارم. امیدوارم که مفید باشه. این متن شامل نیمفاصله است."
# اعمال نرمالسازی برای متن
normalized_text = normalizer.normalize(text)
print(f"متن نرمالشده: {normalized_text}")
# گام سوم: توکنایزر کلمات (word_tokenizer)
# با استفاده از توکنایزر hazm، کلمات متن را جدا میکنیم
tokens = word_tokenize(normalized_text)
print(f"کلمات توکنشده: {tokens}")
# گام چهارم: توکنایزر جملات (sentence_tokenizer)
# اگر نیاز داریم که جملات را جدا کنیم (برای تقسیمبندی متن به جملات)
sentence_tokenizer = SentenceTokenizer()
sentences = sentence_tokenizer.tokenize(normalized_text)
print(f"جملات توکنشده: {sentences}")
# گام پنجم: روش Rule-based برای توکنسازی نیمفاصله
# در اینجا، نیمفاصلهها را هم جدا میکنیم
import re
def rule_based_tokenizer(text):
# ابتدا نیمفاصلهها را جدا میکنیم
text = re.sub(r'([^\s])([ـ])([^\s])', r'\1 \2 \3', text)
# سپس از فاصله برای تقسیم کلمات استفاده میکنیم
return text.split()
# اعمال توکنایزر Rule-based
tokens_rule_based = rule_based_tokenizer(normalized_text)
print(f"کلمات توکنشده با روش Rule-based: {tokens_rule_based}")
توضیحات قطعه به قطعه:
1. نصب کتابخانههای مورد نیاز
در ابتدا باید کتابخانه Hazm را نصب کنیم که به کمک آن میتوانیم متون فارسی را نرمالسازی کرده و توکنایزر بسازیم. همچنین، برای استفاده از توکنایزرهای جملات نیز نیاز داریم تا از ابزار SentenceTokenizer استفاده کنیم.
pip install hazm
2. نرمالسازی متن
در این مرحله با استفاده از Normalizer از کتابخانه Hazm، متن فارسی را نرمالسازی میکنیم. این مرحله شامل تبدیل حروف عربی به فارسی و حذف علائم غیرضروری است.
normalizer = Normalizer()
normalized_text = normalizer.normalize(text)
print(f"متن نرمالشده: {normalized_text}")
نتیجهی نرمالسازی، یک متن یکدستتر است که آماده برای پردازش بیشتر میشود. مثلا:
سلام! من یک پروژه برای ساخت توکنایزر فارسی دارم. امیدوارم که مفید باشه. این متن شامل نیمفاصله است.
3. توکنسازی کلمات (Word Tokenization)
در این مرحله، با استفاده از word_tokenize از کتابخانه Hazm، متن نرمالشده را به کلمات جداگانه تقسیم میکنیم. این توکنایزر با توجه به ساختار زبان فارسی به خوبی عمل میکند.
tokens = word_tokenize(normalized_text)
print(f"کلمات توکنشده: {tokens}")
نتیجه به صورت لیستی از کلمات خواهد بود:
['سلام', '!', 'من', 'یک', 'پروژه', 'برای', 'ساخت', 'توکنایزر', 'فارسی', 'دارم', '.', 'امیدوارم', 'که', 'مفید', 'باشه', '.', 'این', 'متن', 'شامل', 'نیمفاصله', 'است', '.']
4. توکنسازی جملات (Sentence Tokenization)
در برخی مواقع، نیاز به تقسیم متن به جملات داریم. برای این کار از SentenceTokenizer استفاده میکنیم که به صورت خودکار جملات را بر اساس علائم نقطهگذاری (مانند نقطه و سوال) جدا میکند.
sentence_tokenizer = SentenceTokenizer()
sentences = sentence_tokenizer.tokenize(normalized_text)
print(f"جملات توکنشده: {sentences}")
نتیجه به صورت لیستی از جملات خواهد بود:
['سلام!', 'من یک پروژه برای ساخت توکنایزر فارسی دارم.', 'امیدوارم که مفید باشه.', 'این متن شامل نیمفاصله است.']
5. توکنایزر Rule-based برای نیمفاصلهها
در زبان فارسی، نیمفاصلهها از چالشهای خاصی هستند. در این مرحله، یک توکنایزر مبتنی بر قوانین (Rule-based) برای جدا کردن نیمفاصلهها پیادهسازی میکنیم. این روش به کمک عبارتهای منظم (regular expressions) نیمفاصلهها را شناسایی کرده و آنها را از متن جدا میکند.
import re
def rule_based_tokenizer(text):
text = re.sub(r'([^\s])([ـ])([^\s])', r'\1 \2 \3', text)
return text.split()
tokens_rule_based = rule_based_tokenizer(normalized_text)
print(f"کلمات توکنشده با روش Rule-based: {tokens_rule_based}")
نتیجه به صورت کلمات و نیمفاصلههای جدا شده خواهد بود:
['سلام', '!', 'من', 'یک', 'پروژه', 'برای', 'ساخت', 'توکنایزر', 'فارسی', 'دارم', '.', 'امیدوارم', 'که', 'مفید', 'باشه', '.', 'این', 'متن', 'شامل', 'نیمفاصله', 'است', '.']