سلام:) در پست و ویدئو قبلی با word embedding ها و مدل برت آشنا شدیم. این دفعه قصدمون این هست که بیشتر درمورد پردازش زبان قبل از دادن متن به مدل های یادگیری ماشین یا یادگیری عمیق صحبت کنیم.
در این پست ابتدا درمورد پردازش زبان انگلیسی صحبت می کنم و در انتها به سراغ زبان فارسی و کتابخانه حضم که یکی از بهترین منابع موجود و عمومی برای پردازش زبان فارسی هست میرم. متاسفانه ویرگول به راحتی gist هارو نمایش نمیده و کد تمام این بخش ها رو میتونید در این پست یا در گیت هاب بنده مشاهده کنید. البته کد زبان فارسی رو در پایین قرار دادم برای دسترسی راحتتر.
ما مدت خیلی زیادی صرف درست کردن یک مدل یا الگوریتم مناسب برای دسته بندی متون، تقسیم بندی اخبار یا پیام های شبکه های اجتماعی یا تشخیص احساسات درون متن می کنیم تا بلکه با هر تغییری در الگوریتم، نتیجه ذره ای بهتر و یا سرعت ران شدن بالاتری داشته باشیم. اما باید اینم درنظر گرفت که گاهی با یک سری تغییر کوچک می تونیم عملکرد بسیار بهتری رو از مدلمون بگیریم. حالا این تغییرات چند مرحله هستند که روی خود متن تغییر تاثیر می ذارند و به اصطلاح اون رو "تمیز تر" می کنند. در این پست ما چندتا از با اهمیت ترین و تاثیر گذارترین قدم هایی رو که با اون ها میتونیم یک متن تمیز تر برای الگوریتممون درست کنیم آشنا میشیم. این قدم ها کلی هستند پس مثلا اگر شما با متن کتاب کار دارین و نه پست های شبکه های اجتماعی میتونید از مرحله جایگزینی ایموجی ها صرف نظر کنید.
در کل 7 قدم هست که معمولا هر کارشناس داده ای اون هارو برای تمیز کردن متن درنظر می گیره:
خیلی وقت ها قبل از بررسی دقیق متن ممکن هست کارشناس عزیز تمام علائم نگارشی رو برای راحتتر شدن کار در مرحله اول حذف کنه. اما درواقع ایموجی ها و یا ایموتیکان ها که مجموعه ای از حروف اضافه هستند یک بخش مهمی از احساسی که در متن وجود دارد رو در خودشون دارند. مثلا "گللل :))))" رو با "گللل :(((((" مقایسه کنید. اگر شما اول کار تمام حروف اضافه رو حذف کنید الگوریتم شما اگر بخواد احساسات جمله رو تشخیص بده هر دورو به عنوان مثبت و خوشحال در نظر میگیره.
چند نمونه از این شکل ها :) و :( و xD و غیره هستند. ما به راحتی می تونیم این هارو با معادل معناییشون جایگزین کنیم.
این هم یکی دیگه از مواردی هست که در متونی که از شبکه های اجتماعی بدست میان زیاد دیده میشه. لینک ها به طور معمول اطلاع خاصی درمورد متن به ما نمی دند و بیشتر دارای یک فرمت مشخص هستند. پس میشه اون هاروهم با استفاده از یک re.sub به راحتی جاگزین کرد. در عبارت ریجکس پایین همونطور که مبینید متن در ابتدا یک http یا https باید داشته باشه و بعد t.co که نمایشگر لینک هایی هست که در توییتر دیده میشه و بعد هم یک سری عدد و حرف داریم.
همونطور که می دونیم کامپیوتر ها و الگوریتم ها توانایی خواندن مثل مارو ندارند. برای همین ما به جای دادن کل جمله به الگوریتم اون رو تکه تکه می کنیم تا هر کلمه رو جدا تشخیص بده و پردازش کند. حالا برای این کار ما هم میتونیم از تابع و ابزار های ساده مثل split استفاده بکنیم، هم از پکیج هایی مثل nltk و spacy. منتها مشکل split با وجود سادگیش این هست که اگر ما جمله ای مثل "Mr. Smith said he's going downtown"رو بدیم، قابل به تشخیص اینکه downtown از نقطه کنارش جدا هست رو نداره و درنتیجه ما یک کلمه با شکل جدید خواهیم داشت که الگوریتم در دیکشنریش نداره و اون رو یک کلمه جدید حساب می کنه.
برای همین هست که پکیج هایی مثل nltk در این کار به بقیه ارجهیت دارند. فقط این رو در ذهن داشته باشید که اگر شما از چیزی مثل مدل BERT استفاده می کنید، اون مدل خودش یک tokenizer برای توکن یا تکه کردن جملات بر اساس دایره لغات از پیش تعیین شده خود الگوریتم، داره و نیازی نیست شما از یک پکیج جدا استفاده کنید.
چند نمونه از این کلمات در انگلیسی "he", "in", "on", "she" هستند. این کلمات به قدری زیاد و در جمله های مختلفی استفاده میشند و عمومی و بدون جهت گیری خاصی هستند که معمولا در اغلب فرآیند های پردازش زبان از متن حذف میشند تا هم الگوریتم راحتتر عملیات خودش رو انجام بده هم سرعت آموزش بیشتر بشه. این لغات به حدی بی تاثیر هستند که حتی گوگل هم در زمان جست و چو برای پیدا کردن بهترین جواب اونهارو نادیده می گیره.
این علائم هم مثل ایست واژه ها هستند و به دلیل اینکه در همه جملات دیده میشند حذف اونها نتایج مثبت بیشتری از منفیشون داره. البته به این توجه کنید که اگر قصد شما پردازش زبان برای تولید یک مدل زبانی یا language model باشه برای حفظ شیوه نگارشی باید علائم رو هم نگه دارید. ما در کد پایین از تابع maketrans استفاده کردیم که با قرار یک لیست از punctuation ها در سومین جایگاه اون به این تابع میگیم تا هرآنچه علائم نگارشی دیدی سر رات حذف کن. خداخیرت بده.
این یکی از مواردی هست که اغلب در زبان هایی مثل انگلیسی یک معذله. چون اگر شما تمام حروف رو به شکل کوچکشون برگردونید، با اینکه تعداد حروف دیکشنری و درنتیجه حافظه اشغال شده توسط الگوریتم کمتر میشه اما بخش زیادی از معنی متن هم ممکنه تغییر کنه. چطور؟ خب ما زمانی که کلماتی مثل "Another", "There" و غیره رو کوچک کنیم تغییری در معنای اونها به وجود نمیاد. اما فرض کنید شما کلمه ای مثل "Bush" که همون رئیس جمهور بوش هست رو کوچک کنید. این کلمه کاملا تغییر معنایی میده و به "bush" به معنی بوته تبدیل میشه :) پس درکل باید امتحان کنید و ببینید عملکرد الگوریتم در دو حالت چطور هست.
هدف هر دو عملیات lemmatization و stemming برگرداندن کلمات به حالت پایه و اصلیشون هست. فقط تفاوت این دو در شیوه انجام این کاره. stemmer یک کلمه رو میگیره و تهش رو به امید درست شدن یک حرف مناسب میزنه. مثلا وقتی studies رو به اون بدیم به ما studi برمیگردونه. اما lemmatizer همین کار رو با یک دیکشنری انجام میده. پس در جواب دادن studies ما کلمه study رو خواهیم داشت.
حالا به طور خلاصه من کد پردازش زبان فارسی رو هم اینجا برای علاقه مندان زبان مادری قرار میدم :)
# installation...pip install hazm # code... from __future__ import unicode_literals from hazm import * #tokenizer word_tokenize('ولی برای پردازش، جدا بهتر نیست؟')['ولی', 'برای', 'پردازش', '،', 'جدا', 'بهتر', 'نیست', '؟'] # stemmer stemmer = Stemmer() stemmer.stem('کتابها') # lemmatizer lemmatizer = Lemmatizer() lemmatizer.lemmatize('میروم') # parts of speeck tagger.tag(word_tokenize('ما بسیار کتاب میخوانیم'))
ممنون که این پست رو خوندین :) امیدوارم براتون مفید بوده باشه! نظرات و پیشنهادات بسیار استقبال میشه پس اگر نکته ای به نظرتون اومد حتما تو قسمت پایین به اشتراک بذارین :)