در متن کاوی منظور از پردازش زبان طبیعی (NLP)، قابلدسترس کردن زبان طبیعی برای ماشین است. پردازش زبان طبیعی، اسناد متنی بدون ساختار را دریافت و درنهایت به شکلی ساختاریافته تبدیل میکنند. در این حالت امکان استخراج اطلاعات از این اسناد وجود دارد. پردازشهای متنی شامل تحلیلهای صرفی و نحوی و معنایی متن ورودی است. قبل از پردازش زبان طبیعی میبایست عمل پیش پردازش بر روی متن به منظور تمیز سازی داد انجام شود. و اولین مرحله در پیش پردازش ، انجام عملیات نرمال سازی متن است.
پیشپردازش متون معمولا شامل موارد زیر است:
- یکسانساز Normalizer
- تشخیص زبان Language Detection
- جداساز جملات Sentence Splitter
- واحدساز Tokenizer
- کلماتایستا Stop Word Remover
در این مبحث به بررسی مورد اول یعنی یکسان سازی حروف در عملیات نرمال سازی متن میپردازیم. منظور از یکسانساز، یکنواخت کردن کاراکترهای استفادهشده در متون است. با توجه به اینکه ممکن است اسناد منتشرشده، از کدگذاریهای متفاوتی استفاده کنند لذا برای بهبود تحلیلهای متنی نیازمند یکسانسازی این متون هستیم. درواقع حذف کدحروف غیر مناسب (مانند اعراب حروف) یا تبدیل کدهای مختلف حروف (مانند کد /ی/ عربی و فارسی) به یک کد واحد در این مرحله انجام میشود. همچنین کلماتی که دارای ساختار نوشتاری مختلف هستند به یک کلمه تبدیل میشود.
در اولین گام باید متون برای استفاده در گام های بعدی به شکلی استاندارد درآیند. از آنجایی که متون مختلف ممکن است بسیار به هم شبیه باشند اما به دلیل تفاوتهای ساده ظاهری از نظرماشین متفاوت باشند؛ به همین دلیل سعی شده است این تفاوتهای سادهی ظاهری برطرف گردد. برای رسیدن به این هدف، قبل از مقایسه متون، پیشپردازشهایی روی آنها آنجام میشود. طبیعتا هر چه این پیشپردازشها قویتر باشد، نتایج حاصل ازمقایسه متون قابل اطمینانتر خواهد بود. لازم به ذکر است که از آن جایی که زبان فارسی جزو زبانهای غیر ساختیافته است با مشکلات بسیار بیشتری نسبت به سایر زبانها مواجه خواهیم شد. متون غیرساختیافته، متونی هستند که پیش فرض خاصی در مورد قالب آنها نداریم و آنها را به صورت مجموعهای مرتب از جملات در نظر میگیریم.
به طور معمول ناسازگاری های موجود در متن شامل موارد زیر است.
- وجود encoding های مختلف برای بعضی از کاراکترها مانند «ی» و «ک»
- فاصله های اضافه
- تب های اضافه
- تنوع نوشتار با حروف بزرگ و کوچک
- روشهای مختلف چسبیدن وندها به کلمات اصلی
- روشهای مختلف اتصال اجزای کلمات مرکب
- کلمات چنداملایی.
- غلط های املایی
- کلمات محاوره ای
- اختصارات
- تمایز بین مجامع به منظور لیست کردن اسامی افراد و گروه ها
- استفاده از اصطلاحات غیر استاندارد و مختصرسازی های غیر رایج (Colo → Colorado)
- …
پردازش زبان فارسی از جهاتی با پردازش زبان انگلیسی تفاوت دارد. در زبان انگلیسی تمامی حروف و تمامی کلمات جدا از هم و با قانونی مشخص نوشته می شوند و این در حالی است که در زبان فارسی بعضی از حروف به هم چسبیده هستند، برخی از حروف جدا ازهم نوشته می شوند، بعضی از کلمات یکپارچه اند، بعضی از کلمات با فاصله یا نیم فاصله به دو یا چند بخش تقسیم می شوند. تمامی حوزه های مرتبط با پردازش زبان طبیعی به نحوی با متون واقعی سروکار دارند. صورت های غیر استاندارد نویسه ها و کلمات به وفور در این نوع متون نوشته دیده می شوند. قبل از این که بتوان از این متون به منظور استفاده در سیستم های تبدیل متن به گفتار، ترجمه ماشینی، بازشناسی حروف فارسی، خلاصه ساز فارسی، جستجو در متون فارسی و غیره استفاده کرد و یا در پایگاه داده ذخیره نمود، باید ابتدا پیش پردازشی روی آن ها انجام گیرد تا صورت های غیر استاندارد به شکل استاندارد تبدیل گردند. اگر حروف، نشانه های نگارشی و کلمات فارسی به شکل یکسانی نوشته نشوند، متون مورد استفاده قابل تحلیل توسط سامانه های رایانه ای نخواهند بود. طی فرایند نرمال سازی، علایم نگارشی، حروف، فاصله های بین کلمات، اختصارات و غیره بدون ایجاد تغییرات معنایی در متن به شکل استاندارد تبدیل می گردند. بنابراین، بایستی از یک استاندارد مشترک برای پیش پردازش و پردازش متون استفاده کرد.
مراحل پردازش متن
در حالت ساده عملیات ینرمال سازی متن با مراحل زیر انجام پذیر است:
- اصلاح انواع حرف «ک» به معادل فارسی آنان.
- اصلاح انواع حرف «ی» به معادل فارسی آنان.
- بررسی همزه و انواع مختلف املاهای موجود و اصلاح هر کدام (به عنوان مثال تبدیل ؤ به و ، ئ به ی ، أ به ا ، إ به ا و…)
- حذف شناسهی همزه از انتهای واژههایی مثل شهداء
- حذف شناسه «آ» به «ا» مانند: آب به اب
- اصلاح نویسهی «طور» در واژههایی مانند به طور، آن طور، این طور و …
- بررسی وجود حرف «ی» در انتهای لغاتی مانند خانهی ما و اصلاح آنان
- حذف تشدید از واژهها
- تبدیل ارقام عربی و انگلیسی به معادل فارسی.
- اصلاح نویسهی نیمفاصله
- اصلاح اعراب و حذف فتحه، کسره و ضمه و همچنین تنوینها
- حذف نیمفاصلههای تکراری
- حذف نویسهی «ـ» که برای کشش نویسههای چسبان مورد استفاده قرار میگیرد. مانند تبدیل«بــــــــر» و «بـــر» به «بر»
- چسباندن پسوندهای «تر»، «ترین» و … به آخر واژهها
- اصلاح فاصلهگذاری «ها» در انتهای واژهها و همچنین پسوندهای «های»، «هایی»، «هایم»، «هایت»، «هایش» و …
- اصلاح فاصلهگذاری «می»، «نمی»، «درمی»، «برمی»، «بی» در ابتدای واژهها
- تبدیل «ه» به «هی»
- تبدیل «ب» متصل به ابتدای واژهها به «به»
- اصلاح فاصلهگذاری پسوندها
- حذف فاصلهها و نیمفاصلههای اضافه بکار رفته در متن
- تصحیح فاصلهگذاری در مورد علائم سجاوندی بدین صورت که علائم سجاوندی به لغات قبل از خود میچسبند و با لغت بعد از خود فاصله خواهند داشت.
نرمال سازی متن با استفاده از کتابخانه JHazm در زبان جاوا
برای اعمال اصلاحات اولیه قبل از هر عملیاتی، بایستی متون مورد پردازش توسط ابزار Normalizer ، مورد اصلاح قرار گیرند. بعد از نرمال سازی متن، معمولا ایست واژه ها را هم که خود نیز از کلمات پرتکرار هستند را برای تعدادی از کاربردها باید حذف کنیم . در ادامه تابع Normalizer از کلاس Normalizer در کتاب خانه jhazm که به منظور نرمال سازی حروف در متن با زبان جاوا توسعه یافته است، آورده شده است. ورودی این تابع سه مقدار بولین است که به ترتیب برای تصحیح کاراکترهای فضای خالی، تصحیح کارکترهای punctuation و تصحیح پسودن ها به کار میرود.
public Normalizer(boolean characterRefinement, boolean punctuationSpacing, boolean affixSpacing) { this.puncAfter = "!:\\.،؛؟»\\]\\)\\}"; this.puncBefore = "«\\[\\(\\{"; this.characterRefinement = true; this.punctuationSpacing = true; this.affixSpacing = true; this.characterRefinement = characterRefinement; this.punctuationSpacing = punctuationSpacing; this.affixSpacing = affixSpacing; this.translations = new MakeTrans(" کی;%۱۲۳۴۵۶۷۸۹۰", " کی؛٪۱۲۳۴۵۶۷۸۹۰"); if (this.characterRefinement) { this.characterRefinementPatterns = new ArrayList(); this.characterRefinementPatterns.add(new RegexPattern("[ـ\\r]", "")); this.characterRefinementPatterns.add(new RegexPattern(" +", " ")); this.characterRefinementPatterns.add(new RegexPattern("\n\n+", "\n\n")); this.characterRefinementPatterns.add(new RegexPattern(" ?\\.\\.\\.", " …")); } if (this.punctuationSpacing) { this.punctuationSpacingPatterns = new ArrayList(); this.punctuationSpacingPatterns.add(new RegexPattern(" ([!:\\.،؛؟»\\]\\)\\}])", "$۱")); this.punctuationSpacingPatterns.add(new RegexPattern("([«\\[\\(\\{]) ", "$۱")); this.punctuationSpacingPatterns.add(new RegexPattern("([!:\\.،؛؟»\\]\\)\\}])([^ !:\\.،؛؟»\\]\\)\\}])", "$۱ $۲")); this.punctuationSpacingPatterns.add(new RegexPattern("([^ «\\[\\(\\{])([«\\[\\(\\{])", "$۱ $۲")); } if (this.affixSpacing) { this.affixSpacingPatterns = new ArrayList(); this.affixSpacingPatterns.add(new RegexPattern("([^ ]ه) ی ", "$۱\u200cی ")); this.affixSpacingPatterns.add(new RegexPattern("(^| )(ن?می) ", "$۱$۲\u200c")); this.affixSpacingPatterns.add(new RegexPattern(" (تر(ی(ن)?)?|ها(ی)?)(?=[ \n!:\\.،؛؟»\\]\\)\\}«\\[\\(\\{]|$)", "\u200c$1")); this.affixSpacingPatterns.add(new RegexPattern("([^ ]ه) (ا(م|ت|ش|ی))(?=[ \n!:\\.،؛؟»\\]\\)\\}]|$)", "$۱\u200c$2")); } }
در ادامه مثالی از نحوه استفاده از این تابع آورده شده است.
String plainText = new String();
String normalizedText = new String();
//use jhazm normalizer to remove empty lines and spaces and ...
Normalizer normalizer = new Normalizer(true, false, false);
normalizedText = normalizer.run(plainText);