build-persian-text-tokenizer_آکادمی تخصصی ریسمان
تاریخ انتشار :
میانگین: 5.0

ساخت توکنایزر برای متون فارسی

توکنایزر یکی از مهم‌ترین ابزارها در پردازش زبان طبیعی (NLP) است که وظیفه‌ی آن شکستن متن به واحدهای کوچکتر مانند جمله، کلمه یا زیرکلمه می‌باشد. در زبان فارسی به دلیل وجود چالش‌هایی مانند نیم‌فاصله، حروف عربی، شکل‌های مختلف نوشتاری و پسوندها، طراحی یک توکنایزر دقیق اهمیت ویژه‌ای دارد.
در این مقاله یک پروژه واقعی ساخت توکنایزر برای متون فارسی را بررسی می‌کنیم و مراحل آن از تعریف نیازمندی‌ها تا پیاده‌سازی و ارزیابی را توضیح خواهیم داد.
روش‌های مختلف توکن‌سازی از رویکردهای ساده مبتنی بر قوانین تا مدل‌های پیشرفته یادگیری ماشین و ابزارهای مدرن مانند SentencePiece نیز معرفی می‌شوند.
همچنین خواهیم دید که چگونه می‌توان خروجی این توکنایزر را در پروژه‌های واقعی مثل موتور جستجو، تحلیل احساسات یا ترجمه ماشینی به کار برد.
این مقاله یک راهنمای جامع برای پژوهشگران، توسعه‌دهندگان و علاقه‌مندان NLP فارسی است که به دنبال ساخت یا بهبود توکنایزر اختصاصی خود هستند.

Share
Pin
Like
Send
Share
Send
Send
Share

معرفی کلی پروژه

توکنایزر (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}")

 

نتیجه به صورت کلمات و نیم‌فاصله‌های جدا شده خواهد بود:

['سلام', '!', 'من', 'یک', 'پروژه', 'برای', 'ساخت', 'توکنایزر', 'فارسی', 'دارم', '.', 'امیدوارم', 'که', 'مفید', 'باشه', '.', 'این', 'متن', 'شامل', 'نیم‌فاصله', 'است', '.']

 

مدیریت پیشوندها و پسوندها
 

from hazm import Normalizer, word_tokenize, SentenceTokenizer
import re

# نرمال‌سازی متن
normalizer = Normalizer()

text = "سلام! من یک پروژه برای ساخت توکنایزر فارسی دارم. امیدوارم که مفید باشه. پیشوندها و پسوندها را مدیریت کنیم."

# اعمال نرمال‌سازی
normalized_text = normalizer.normalize(text)
print(f"متن نرمال‌شده: {normalized_text}")

# توکنایزر کلمات
tokens = word_tokenize(normalized_text)
print(f"کلمات توکن‌شده: {tokens}")

# توکنایزر جملات
sentence_tokenizer = SentenceTokenizer()
sentences = sentence_tokenizer.tokenize(normalized_text)
print(f"جملات توکن‌شده: {sentences}")

# توکنایزر Rule-based برای نیم‌فاصله‌ها
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}")

# گام جدید: مدیریت پیشوندها و پسوندها
# این تابع به صورت دستی پیشوندها و پسوندهای رایج را جدا می‌کند.

def handle_affixes(text):
    # پیشوندها: برای مثال "می"، "با"، "به" و...
    text = re.sub(r'^(می|با|به|در|از)([^\s]+)', r'\1 \2', text)
    
    # پسوندها: برای مثال "ها"، "های" و...
    text = re.sub(r'([^\s]+)(ها|های|تان|شده|شده‌اند|مان)', r'\1 \2', text)
    
    return text

# اعمال توکنایزر و مدیریت پیشوند و پسوند
text_with_affixes = handle_affixes(normalized_text)
print(f"متن با پیشوندها و پسوندها: {text_with_affixes}")

# اجرای توکنایزر دوباره بعد از مدیریت پیشوندها و پسوندها
tokens_with_affixes = word_tokenize(text_with_affixes)
print(f"کلمات توکن‌شده با مدیریت پیشوندها و پسوندها: {tokens_with_affixes}")

# گام جدید: جدا کردن اعداد و تاریخ‌ها
def handle_numbers_and_dates(text):
    # جدا کردن اعداد
    text = re.sub(r'(\d+)', r' \1 ', text)  # اعداد را به عنوان یک توکن جداگانه در نظر می‌گیریم
    
    # جدا کردن تاریخ‌ها (این بخش برای مثال تاریخ‌های شمسی ساده است)
    text = re.sub(r'(\d{4})/(\d{2})/(\d{2})', r'\1/\2/\3', text)  # مثال تاریخ: 1400/05/01
    
    return text

# اعمال توکنایزر با مدیریت اعداد و تاریخ‌ها
text_with_numbers = handle_numbers_and_dates(text_with_affixes)
print(f"متن با اعداد و تاریخ‌ها: {text_with_numbers}")

# توکن‌سازی مجدد با تاریخ و اعداد
tokens_with_numbers = word_tokenize(text_with_numbers)
print(f"کلمات توکن‌شده با اعداد و تاریخ‌ها: {tokens_with_numbers}")

 

مدیریت پیشوندها و پسوندها

در زبان فارسی، کلمات ممکن است پیشوندهایی مثل "می"، "با"، "به" داشته باشند یا پسوندهایی مثل "ها"، "های"، "تان" اضافه شوند. برای جدا کردن این پیشوندها و پسوندها از کلمات، از عبارت‌های منظم (regular expressions) استفاده می‌کنیم.

  • پیشوندها: مثل "می‌روم" → ["می", "روم"]

  • پسوندها: مثل "کتاب‌ها" → ["کتاب", "ها"]
     

    def handle_affixes(text):
        # پیشوندها: برای مثال "می"، "با"، "به" و...
        text = re.sub(r'^(می|با|به|در|از)([^\s]+)', r'\1 \2', text)
        
        # پسوندها: برای مثال "ها"، "های" و...
        text = re.sub(r'([^\s]+)(ها|های|تان|شده|شده‌اند|مان)', r'\1 \2', text)
        
        return text
    

     

جدا کردن اعداد و تاریخ‌ها

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

  • اعداد: مثلا "۱۰۰" → [100]

  • تاریخ‌ها: مثل "1400/05/01" → ["1400/05/01"]
     

    def handle_numbers_and_dates(text):
        # جدا کردن اعداد
        text = re.sub(r'(\d+)', r' \1 ', text)  # اعداد را به عنوان یک توکن جداگانه در نظر می‌گیریم
        
        # جدا کردن تاریخ‌ها (این بخش برای مثال تاریخ‌های شمسی ساده است)
        text = re.sub(r'(\d{4})/(\d{2})/(\d{2})', r'\1/\2/\3', text)  # مثال تاریخ: 1400/05/01
        
        return text
    

    اجرای توکنایزر

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

    نکات تکمیلی:

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

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

  • اگر نیاز به انجام تحلیل‌های بیشتر دارید (مثل تحلیل احساسات یا استخراج اطلاعات)، این توکنایزر می‌تواند ورودی مناسبی فراهم کند.

جمع‌بندی

  • در این کد، ابتدا متن فارسی را نرمال‌سازی کرده و سپس از Hazm برای توکنایزر کلمات و جملات استفاده کردیم.

  • در ادامه، با استفاده از یک روش Rule-based، نیم‌فاصله‌ها را از متن جدا کردیم.

  • این کد به شما کمک می‌کند که با استفاده از ابزارهای ساده و پیشرفته، یک توکنایزر خوب برای متون فارسی بسازید که می‌توانید در پروژه‌های NLP خود استفاده کنید.

این کد به خوبی پایه‌گذار ساخت یک توکنایزر فارسی است و می‌توان آن را برای پروژه‌های پیچیده‌تر گسترش داد.

کلیدواژه ها

توکنایزر,پردازش زبان طبیعی,هوش مصنوعی,یادگیری ماشین,مدل‌های زبانی,تحلیل متن,جستجو,nlp فارسی,ابزارهای پردازش متن,ساخت توکنایزر فارسی

پرسش و پاسخ

1 . توکنایزر فارسی چیست و چرا به آن نیاز داریم؟
توکنایزر فارسی ابزاری است که متن را به اجزای کوچک‌تر مثل کلمات یا جملات تقسیم می‌کند. این کار برای بسیاری از کاربردهای NLP مثل تحلیل احساسات، ترجمه ماشینی و جستجو ضروری است، چون کامپیوترها نمی‌توانند مستقیماً متن را به شکل خام درک کنند.

2 . تفاوت توکنایزر فارسی با انگلیسی چیست؟
در زبان فارسی به دلیل وجود چالش‌هایی مثل نیم‌فاصله، پسوندها و پیشوندها (مثلاً "کتاب‌ها" یا "می‌روم") و حتی اعداد و تاریخ‌ها، طراحی توکنایزر سخت‌تر از انگلیسی است. به همین دلیل نیاز به ابزارها و الگوریتم‌های اختصاصی برای زبان فارسی داریم.

3 . چگونه می‌توان پیشوندها و پسوندها را در توکنایزر فارسی مدیریت کرد؟
می‌توان از روش‌های مبتنی بر قواعد (Rule-based) یا یادگیری ماشین استفاده کرد. در روش Rule-based با کمک Regular Expressions پیشوندهایی مثل "می-" یا "به-" و پسوندهایی مثل "-ها"، "-تان" جدا می‌شوند. در روش یادگیری ماشین، مدل‌ها بر اساس داده‌های آموزش‌یافته به‌طور هوشمند این جداسازی را انجام می‌دهند.

4 . آیا Hazm بهترین ابزار برای توکن‌سازی متون فارسی است؟
Hazm یکی از پرکاربردترین و ساده‌ترین کتابخانه‌های پردازش متن فارسی است و برای پروژه‌های آموزشی و حتی بسیاری از پروژه‌های واقعی مناسب است. با این حال، در پروژه‌های پیچیده‌تر می‌توان از مدل‌های پیشرفته‌تر مثل ParsBERT یا توکنایزرهای مبتنی بر Transformerها استفاده کرد.

5 . چگونه می‌توان اعداد و تاریخ‌ها را در متن فارسی به‌درستی توکن‌سازی کرد؟
برای جداسازی اعداد و تاریخ‌ها می‌توان از عبارت‌های منظم (Regex) استفاده کرد. مثلاً عدد "1400" یا تاریخ "1400/05/01" به‌صورت توکن مجزا جدا می‌شود. این کار باعث می‌شود که تحلیل متن در پروژه‌هایی مثل استخراج اطلاعات یا پردازش داده‌های بانکی و تاریخی دقیق‌تر انجام شود.

دیدگاه ها

برای ارسال دیدگاه وارد حساب کاربری خود شوید.