خانه / علم داده / پردازش زبان طبیعی / پردازش متون فارسی با پایتون – بخش اول
text-Mining

پردازش متون فارسی با پایتون – بخش اول

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

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

برای شروع ابتدا مفاهیم و اصطلاحات و ابزاری  که در ادامه آموزش به کار خواهیم برد را مرور می کنیم :‌ (مرجع : آزمایشگاه وب دانشگاه فردوسی)

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

مهمترین ابزارهای پردازش زبان طبیعی در متون عبارتند از:

  • تشخیص دهنده ی جمله: این ابزار باید با توجه به کاراکترهای جداکننده ی جمله در زبان فارسی، توانایی تشخیص جملات را در متن ورودی داشته باشد. برای ایجاد این ابزار باید ابتدا تمامی کاراکترها، نماد ها و احیاناً قواعد دستوری که باعث شکسته شدن جملات می شوند، شناسایی گردند. با توجه به پایه بودن جمله در بسیاری از پردازش های زبانی، خروجی دقیق این ابزار از درجه ی اهمیت بالایی برخوردار است. از نمونه های انگلیسی آن می توان به OpenNLP، Stanford NLP، NLTK و Freeling اشاره کرد.
  • Tokenizer: ابزاری برای شکستن یک متن بر اساس واحدهای با معنی مانند کلمه، پاراگراف، نمادهای معنادار مانند space و  tab و … . لازمه ی ایجاد این ابزار جمع آوری واحد هایی است که در زبان فارسی به عنوان واحد های مستقل معنایی شناخته می شوند. سپس بر اساس انتخاب هر کدام از این واحدها متن بر اساس آن شکسته خواهد شد. از نمونه های انگلیسی آن می توان به Flex، JLex، JFLex، ANTLR، Ragel و Quex اشاره کرد.
  • Named entity recognition: ابزاری برای تشخیص اسامی و نوع آنها اعم از اسامی افراد، اماکن، مقادیر عددی و … . برای تشخیص اینکه یک کلمه اسم است، راه های مختلفی وجود دارد که از جمله ی آنها مراجعه به لغتنامه، مراجعه به word-net، در نظر گرفتن ریشه ی کلمه، استفاده از قواعد نحوی ساخت واژه و … می باشد. در این ابزار پس از تشخیص اسم ها با استفاده یک لغتنامه از اسامی افراد، مکان ها، مقادیر عددی و … نوع اسم تشخیص داده می شود. به نظر می رسد که این لغتنامه در فارسی موجود نمی باشد.از جمله نمونه های انگلیسی این ابزار می توان به Stanford NER و Illinois NER اشاره کرد.
  • Word-net: مجموعه ای از لغات و ارتباط میان آنها به لحاظ معنایی. ارتباطات معنایی در داخل این مجموعه شامل ۱۶  رابطه  می باشد. این مجموعه به عنوان یک مرجع در بسیاری از پردازش های زبانی مورد استفاده قرار می گیرد. ار نمونه های انگلیسی آن می توان به Princeton Wordnet و EuroWordnet اشاره کرد. آزمایشگاه فناوری وب دانشگاه فردوسی مشهد نیز یک نمونه از این مجموعه با نام فردوس نت را تولید کرده است.
  • Stemmer: ابزاری برای ریشه یابی لغات و تشخیص نوع کلمه ساخته شده از آن ریشه (اسم مکان، اسم زمان، حالت فاعلی، مفعولی و …). معمولاً ریشه یابی لغات بر اساس قواعد ساخت واژه ای و سپس حذف پسوندها می باشد. تاکنون روش مؤثری برای حذف پیشوندها ارائه نشده است. در تلاشی که در آزمایشگاه فناوری وب انجام شده است، سعی شده تا بر اساس آنالیزهای آماری و داده کاوی پسوندها حذف گردند، که این روش هم می تواند راهی برای تشخیص ریشه باشد. معروفترین الگوریتم ریشه یابی در انگلیسی porter می باشد. البته ما در بحث ریشه یابی دو رهیافت مختلف داریم : stemming و Lemmatizing . در stemming ما به تک واژه ها نگاه می کنیم و به کلمات اطراف اون لغت، کاری نداریم . بنابراین ترجمه فارسی آنرا می توانیم ریشه یاب لغوی ترجمه کنیم اما در Lemmatizing ما بر اساس نوع کلمه و بستری که یک کلمه در آن به کار رفته است به ریشه یابی یک کلمه مبادرت می ورزیم بنابراین فرآیند Lemmatizing وقت گیر و حرفه ای تر است و نیاز به پردازش های دیگری مانند POS Tagging هم دارد که نقش کلمه در جمله را ابتدا معین کند . این فرآیند را می توانیم ریشه یاب گرامری ترجمه کنیم.
  • Similarity recognition: ابزاری برای تشخیص میزان شباهت میان دو عبارت بر اساس پارامترهای مختلف مانند نوع اسامی مشابه به کار رفته، استفاده از word-net و… . در این ابزار پس از تشخیص نوع کلمات به کار رفته در یک جمله و سپس بر اساس جایگاه آن کلمات در جمله، کلماتی که در جایگاه های یکسان قرار دارند، مورد مقایسه قرار می گیرند. از نمونه های انگلیسی آن می توان به Illinois NESim و Illinois WNSim اشاره نمود.
  • Chunker: ابزاری برای تشخیص گروه های اسمی، فعلی و …. در یک جمله. جهت تقویت الگوریتم های وابسته به SRL لازم است نه تنها نقش های کلمات مشخص گردند، بلکه باید وابستگی های کلمات به لحاظ نقشی در جمله مشخص گردند. از جمله نمونه های انگلیسی آن می توان به Illinois Chunker  اشاره کرد.
  • Semantic role labeler: ابزاری برای تشخیص نقش گرامری کلمه در جمله. این ابزار یکی از مهمترین نقش ها را در پردازش های زبانی بر عهده دارد. دقت در این ابزار بسیار حائز اهمیت است. این ابزار باید نقش های گرامری کلمات در جمله ها مانند فعل، فاعل، مفعول مستقیم، مفعول غیر مستقیم و …. را تشخیص دهد. از جمله نمونه های انگلیسی آن می توان به OpenNlP، Illinois SRL، Swirl و LTHSRL  اشاره کرد. این ابزارها از الگوریتم پارسینگ charniak استفاده می کنند.
  • Annotator: ابزاری برای ایجاد یک نمونه از یک آنتولوژی در یک سند داده شده. از ابزارهای موجود در انگلیسی می توان به Illinois Curator و Stanford Annotator اشاره کرد.
  • Coreference resolution: ابزاری برای تعیین مرجع اسمی یک اسم یا یک ضمیر در جملات. این ابزار در زبان انگلیسی معادل ابزاری است که مرجع ضمیر را که به صورت اسم در جمله های قبلی آمده است، مشخص می کند. استفاده از ضمایر به جای اسامی در زبان انگلیسی بسیر رایج می باشد. اما در زبان فارسی این امر چندان رایج نیست. اما در زبان فارسی عنوان یک مفهوم اسمی با اصطلاحات مختلف بسیار رایج می باشد. عملاً ما به دنبال ابزاری هستیم که مرجع خاص یک سری از عنوان ها ی مختلف اسمی را مشخص کند. از نمونه های انگلیسی این ابزار می توان به Illinois Coreference package  اشاره کرد.
  • Pos tagger (برچسب گذار اجزای واژگانی کلام): ابزاری برای مشخص کردن نوع کلمات از قبیل اسم، صفت، قید، فعل و … و برچسب گذاری کلمات.به عمل انتساب برچسب های واژگانی (اسم، صفت، قید، فعل و …) به کلمات و نشانه های تشکیل دهنده یک متن POS Tagging می گوییم؛ به صورتی که این برچسب ها نشان دهنده نقش کلمات و نشانه ها در جمله باشد. درصد بالایی از کلمات از نقطه نظر برچسب واژگانی دارای ابهام هستند، زیرا کلمات در جایگاههای مختلف برچسب های واژگنی متفاوتی دارند. بنابراین برچسب گذاری واژگانی عمل ابهام زدایی از برچسب ها با توجه به زمینه (متن) مورد نظر است. برچسب گذاری واژگانی عملی اساسی برای بسیاری از حوزه های دیگر پردازش زبان طبیعی(NLP) از قبیل ترجمه ماشینی، خطایاب و تبدیل متن به گفتار می باشد. تا کنون مدل ها و روش های زیادی برای برچسب گذاری در زبان های مختلف استفاده شده است. بعضی از این روش ها عبارتند از:
    •   مدل مخفی مارکوف (Markov Hidden Model)
    •   برچسب گذاری مبتنی بر تبدیل یا قانون (Transformation/Rule -based tagger)
    •   سیستم های مبتنی بر حافظه (Memory-basedSystem
    •   سیستم های ماکزیمم آنتروپی (Maximum Entropy System)

    یکی دیگر از روش های کاری برای ایجاد این ابزار، ایجاد یک rule base که معمولاً به صورت دستی تشکیل می شود، برای تشخیص نوع کلمه است. از نونه های فارسی آن می توان به ابزار آزمایشگاه آقای دکتر بیجن خان، و ابزار آزمایشگاه فناوری وب دانشگاه فردوسی مشهد اشاره کرد. از نمونه های انگلیسی آن می توان به Illinois Part Of Speech Tagger و Stanford POS Tagger اشاره کرد.

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

نرمالسازی متن

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

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

در ابتدا بایستی همه ­ی نویسه‌های (کاراکترهای) متن با جایگزینی با معادل استاندارد آن یکسان­سازی گردند. در پردازش رسم الخط زبان فارسی، با توجه به قرابتی که با رسم الخط عربی دارد، همواره در تعدادی از حرف­ها مشکل وجود دارد که از جمله آن­ها می­توان به حروف “ک”، “ی”، همزه و … اشاره نمود. در اولین گام باید مشکلات مربوط به این حروف را برطرف ساخت. علاوه بر این، اصلاح و یکسان سازی نویسه‌ی نیم‌فاصله و فاصله در کاربردهای مختلف آن و همچنین حذف نویسه­ی «ـ» که برای کشش نویسه­های چسبان مورد استفاده قرار می­گیرد و مواردی مشابه برای یکسان­سازی متون، از اقدامات لازم قبل از شروع فاز‌های مختلف می­باشد. در این فاز مطابق با یک سری قاعده دقیق و مشخص، فاصله­ ها و نیم­فاصله­ های موجود در متن برای علاماتی نظیر “ها” و “ی” غیرچسبان در انتهای لغات و همچنین پیشوندها و پسوندهای فعل­ساز نظیر “می”، “ام”، “ایم”، “اید” و موارد مشابه جهت استفاده در فازهای بعدی، اصلاح می­گردند.

برخی از این اصلاحات در ذیل آورده شده است:

  • اصلاح انواع حرف «ک» به معادل فارسی آنان.
  • اصلاح انواع حرف «ی» به معادل فارسی آنان.
  • بررسی همزه و انواع مختلف املاهای موجود و اصلاح هر کدام (به عنوان مثال تبدیل ؤ به و ، ئ به ی ، أ به ا ، إ به ا و…)
  • حذف شناسه‌ی همزه از انتهای واژه‌هایی مثل شهداء
  • حذف شناسه «آ» به «ا» مانند: آب به اب
  • اصلاح نویسه‌ی «طور» در واژه‌هایی مانند به طور، آن طور، این طور و …
  • بررسی وجود حرف «ی» در انتهای لغاتی مانند خانه‌ی ما و اصلاح آنان
  • حذف تشدید از واژه‌ها
  • تبدیل ارقام عربی و انگلیسی به معادل فارسی.
  • اصلاح نویسه‌ی نیم‌فاصله
  • اصلاح اعراب و حذف فتحه، کسره و ضمه و همچنین تنوین‌ها
  • حذف نیم‌فاصله‌های تکراری
  • حذف نویسه‌ی «ـ» که برای کشش نویسه­های چسبان مورد استفاده قرار می­گیرد. مانند تبدیل«بــــــــر» و «بـــر» به «بر»
  • چسباندن پسوندهای «تر»، «ترین» و … به آخر واژه‌ها
  • اصلاح فاصله‌گذاری «ها» در انتهای واژه‌ها و همچنین پسوندهای «های»، «هایی»، «هایم»، «هایت»، «هایش» و …
  • اصلاح فاصله‌گذاری «می»، «نمی»، «درمی»، «برمی»، «بی» در ابتدای واژه‌ها
  • تبدیل «‍ة» به «‍ه‌ی»
  • تبدیل «ب» متصل به ابتدای واژه‌ها به «به»
  • اصلاح فاصله‌گذاری پسوندها
  • حذف فاصله‌ها و نیم‌فاصله‌های اضافه بکار رفته در متن
  • تصحیح فاصله‌گذاری در مورد علائم سجاوندی بدین صورت که علائم سجاوندی به لغات قبل از خود می‌چسبند و با لغت بعد از خود فاصله خواهند داشت.

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

ایست واژه ها یا Stop Words:  ایست واژه ها کلماتی هستند که با وجود تکرار فراوان در متن دارای اهمیت کمی از نظر معنایی می باشند. از جمله این کلمات در فارسی می توان به “اگر”، “و”، “ولی”، “که” و غیره اشاره کرد. در نگاه اول تصور بر این است که فقط کلمات ربط و تعریف ایست واژه هستند ولی بسیاری از افعال، افعال کمکی، اسمها، قید ها و صفات نیز به عنوان ایست واژه شناخته شده اند. در اغلب عملیات متن کاوی با حذف این کلمات نتیجه پردازش به شدت بهبود می یابد و سبب کاهش بار محاسباتی و افزایش سرعت می شود. برای زبان فارسی نیز چند لیست ایست واژه ایجاد شده که به طور میانگین دارای ۵۰۰ کلمه می باشند.

برای ادامه مباحث آموزشی از کتابخانه هضم و NLTK استفاده خواهیم کرد و به ترتیب، مفاهیم پایه پردازش متن را با انجام مثالهایی عملی مرور خواهیم نمود .

بد نیست نگاهی اجمالی به امکانات اولیه کتابخانه هضم بیندازیم :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
>>> from __future__ import unicode_literals
>>> from hazm import *

>>> normalizer = Normalizer()
>>> normalizer.normalize('اصلاح نويسه ها و استفاده از نیم‌فاصله پردازش را آسان مي كند')
'اصلاح نویسه‌ها و استفاده از نیم‌فاصله پردازش را آسان می‌کند'

>>> sent_tokenize('ما هم برای وصل کردن آمدیم! ولی برای پردازش، جدا بهتر نیست؟')
['ما هم برای وصل کردن آمدیم!', 'ولی برای پردازش، جدا بهتر نیست؟']
>>> word_tokenize('ولی برای پردازش، جدا بهتر نیست؟')
['ولی', 'برای', 'پردازش', '،', 'جدا', 'بهتر', 'نیست', '؟']

>>> stemmer = Stemmer()
>>> stemmer.stem('کتاب‌ها')
'کتاب'
>>> lemmatizer = Lemmatizer()
>>> lemmatizer.lemmatize('می‌روم')
'رفت#رو'

>>> tagger = POSTagger(model='resources/postagger.model')
>>> tagger.tag(word_tokenize('ما بسیار کتاب می‌خوانیم'))
[('ما', 'PRO'), ('بسیار', 'ADV'), ('کتاب', 'N'), ('می‌خوانیم', 'V')]

>>> chunker = Chunker(model='resources/chunker.model')
>>> tagged = tagger.tag(word_tokenize('کتاب خواندن را دوست داریم'))
>>> tree2brackets(chunker.parse(tagged))
'[کتاب خواندن NP] [را POSTP] [دوست داریم VP]'

>>> parser = DependencyParser(tagger=tagger, lemmatizer=lemmatizer)
>>> parser.parse(word_tokenize('زنگ‌ها برای که به صدا درمی‌آید؟'))

 

فایل wtlab Section 2-4 در آزمایشگاه فناوری وب دانشگاه فردوسی  را نیز توصیه می کنم حتما مشاهده کنید.

پی نوشت :

به همت کافه آی تی ، سلسله کارگاه هایی در حوزه متن کاوی فارسی برگزار شده است که برخی از ویدئوهای این کارگاه را می توانید در زیر مشاهده نمائید :

  1. متن کاوی در وب فارسی-۱
  2. متن کاوری در وب فارسی-۲
  3. متن کاوری در وب فارسی – ۳
  4. متن کاوی در وب فارسی – نشست دوم – ۱
  5. متن کاوی در وب فارسی – نشست دوم -۲
  6. متن کاوی در وب فارسی – نشست دوم -۳

ادامه دارد .

۲ نظرات

  1. آقا مطالب شما واقعاَ ارزشمنده.

    هیچ منبع فارسی مثل شما وجود نداره که اینقدر خوب مباحث دانش داده رو پوشش داده باشه.

    با آرزوی سلامتی

  2. سلام دوست عزیز

    من یه مشکلی دارم

    متن فارسی رو برای من تو \ایتون اینطوری میاره

    مثلا این کد خروجی زیر رو داره
    from __future__ import unicode_literals
    from hazm import sent_tokenize, word_tokenize
    word_tokenize(‘حمید’)
    [u’\u062d\u0645\u06cc\u062f’]

    خب من الان این رو چه کنم؟

    تو متن بالا و تمام جاهایی که توضیح دادن راحت نوشته شده که باید در خروجی حمید بیاد اما برای من اینطوریه

    من \ایتون ۲٫۷٫۱۲ و لینوکس مینت دارم.

    ممنون

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Time limit is exhausted. Please reload CAPTCHA.