فهرست مطالب
پیادهسازی تکنیک بردارسازی TF-IDF
همانطور که پیشازاین گفتیم برای ساختن ماتریس document-term کتابخانه Scikit-learn، انواع vectorizerهای مختلفی مانند Count ،tf-idf و hash ارائه میدهد. در مقاله bag of words چیست نحوه کارکردن با CountVectorizer را دیدیم. در این مقاله توضیح میدهیم tf-idf چیست و با روش جامعتری به نام tf-idf vectorization برای بردارسازی متن آشنا میشویم که میتوانیم آن را برای پروژههای text classification نیز استفاده کنیم.
TF-IDF چیست؟
در بردارسازی متن، مشکل CountVectorizer و شمارش تعداد تکرار کلمات این است که برخی از کلمات فقط در تعداد محدودی از داکیومنتها استفاده شدهاند؛ بنابراین مدل، این الگو را یاد گرفته و بر روی دادههای آموزشی overfit یا بیشبرازش میشود و نمیتواند الگویی که یاد گرفته را بر روی متنهای جدید تعمیم دهد (مقاله تفاوت بایاس و واریانس را بخوانید). از طرف دیگر کلماتی که در همه داکیومنتها وجود دارند، هیچ اطلاعات یا الگوی خاصی به مدل classifier آموزش نمیدهند.
به عبارت خودمانیتر: کلمات کمتکرار و پرتکرار کمک چندانی به تحلیل ما نمیکنند، پس بهتر است فیلتر شوند. سادهترین روش فیلترکردن استفاده از max_df و min_df است. پس چه نیازی به بردارسازی متن با tf-idf vectorization است؟
tf-idf vectorization یک مرحله نرمالسازی دارد که باعث میشود ترجیحاً کلمات کممعنی و کماهمیت بهصورت خودکار شناسایی شوند.
در ادامه جزئیتر بررسی خواهیم کرد که tf-idf چیست:
- Tf مخفف عبارت term frequency است، یعنی تعداد دفعاتی که یک کلمه در هر داکیومنت استفاده شده است. ما این شمارش را در مقاله قبل به کمک CountVectorizer انجام دادیم.
- Idf مخفف عبارت inverse document frequency است، یعنی معکوس تعداد داکیومنتهایی که یک کلمه در آنها بهکار رفته است. Idf میزان اهمیت یک کلمه را نسبت به کل corpus اندازهگیری میکند.
اگر tf را در idf ضرب کنیم، مقدار tf-idf score به دست میآید:
که در آن:
- t : یک کلمه یا توکن است.
- d : نشاندهنده داکیومنت موردنظر است.
- D : نشاندهنده همه داکیومنتهایی است که در corpus وجود دارند.
مقدار tf-idf score یک عدد اعشاری است که میزان اهمیت یک کلمه را در یک داکیومنت نشان میدهد. به کلمات پرتکراری که در همه داکیومنتها استفاده شدهاند امتیاز کمتر و به کلماتی که در کل corpus کاربرد کمتری داشتهاند، وزن و امتیاز بالاتری تعلق میگیرد.
به زبان خودمانیتر: هرچقدر کلمه در داکیومنتهای بیشتری باشد امتیاز کمتری میگیرد و برعکس.
در دوره آموزش متن کاوی فارسی با شبکههای عصبی با تمرکز روی زبان فارسی، جدیدترین تکنیکهای پردازش زبان طبیعی با کدنویسی فراوان آموزش داده میشود.
محاسبه TF-IDF
برای بردارسازی متن و پیادهسازی tf-Idf به کمک کتابخانه scikit-learn میتوانیم از TfidfVectorizer استفاده کنیم (برای اطلاعات بیشتر به scikit-learn documentation مراجعه کنید).
بسته به اینکه بخواهیم تأثیر کلمات نادر و کم کاربرد را به حداکثر برسانیم یا اینکه نقش کلمات پرتکرار را کم کنیم، روشهای مختلفی برای محاسبه مقدار tf یا مقدار idf وجود دارد. بهاینترتیب، با استفاده از این روشهای مختلف، مقادیر متفاوتی برای tf-idf خواهیم داشت.
بهعنوانمثال، وقتی که داکیومنتهایی با اندازههای مختلف داخل یک corpus باشد، بهتر است یک مرحله نرمالسازی طبق فرمول زیر داشته باشیم:
در این فرمول، n تعداد دفعاتی است که کلمه t در داکیومنت d بهکاررفته است.
به طور مشابه، میتوان مقدار idf را نیز با استراتژیهای وزنی مختلف محاسبه کرد. TfidfVetorizer روشهای مختلف محاسبه tf-idf را از طریق پارامترهای خودش مانند sublinear_tf ،smooth_idf و norm فراهم کرده است.
البته در اکثر مواقع، پارامترهای پیشفرضی که خود scikit-learn ارائه داده، مناسب است و میتوانیم از همان مقدار پیشنهادی خودشان را در بردارسازی متن استفاده کنیم.
مقایسه CountVectorizer و TfidfVectorizer
حال که فهمیدیم tf-idf چیست و چطور محاسبه می شود، احتمالا برای شما نیز سوال است که آیا همیشه از tf-idf استفاده کنیم؟
اینکه بین دو روش بردارسازی متن CountVectorizer و TfidfVectorizer کدام را انتخاب کنیم، کاملاً به ماهیت متن و داکیومنتهایی که با آنها کار میکنیم، بستگی دارد. لزوماً روش tf-idf همیشه نتایج بهتری ندارد!
در دو حالت زیر استفاده از روش tf یا همان CountVectorizer، میتواند نتایج بهتری در مقایسه با tf-idf داشته باشد:
- اگر توزیع کلمات documentهای مختلف تقریباً یکسان باشند، نرمالسازی با استفاده از idf، تأثیر زیادی نخواهد داشت. این حالت در متن Brown corpus دیده میشود. یعنی در داکیومنتهای مختلف تقریباً از کلمات یکسانی استفاده شده است. بهاینترتیب، درنظرگرفتن میزان تأثیر هر کلمه نسبت به کل corpus، فایدهای ندارد زیرا عملکرد مدل را بهبود نمیدهد.
- اگر کلمات کمیاب یا کمکاربرد، معنای ارزشمندی برای مدل classification نداشته باشند، دیگر استفاده از روش tf-idf مزیت خاصی ندارد. بهعنوانمثال، هنگامی که کاربر در شبکههای اجتماعی از کلمات و عبارات خلاصه شده استفاده کند که کمتکرار باشند ولی لزوماً معنی ارزشمندی نخواهند داشت، مثل کلمه “asap” که مخفف عبارت “as soon as possible” هست.
برای آشنایی کامل و پروژه محور با مفاهیم پردازش زبان طبیعی دوره آموزش پردازش زبان طبیعی مقدماتی را ببینید.
محدودیتهای TF-IDF چیست؟
محدودیت جدی و اول، بزرگی ابعاد ماتریس ویژگیها است. بهعنوانمثال، اگر یک corpus انتخاب کنیم که 4 داکیومنت داشته باشد، بردار کلمه 4 بعدی است و اگر corpus موردنظر 1000 داکیومنت داشته باشد، بردار کلمه 1000 بعدی است.
یعنی عیبی که در روش بردارسازی متن با CountVectorizer هم بود. البته به کمک Tf-idf و بر اساس امتیازات آن، برخی از کلمات فیلتر شدند، ولی باز بااینوجود ابعاد ماتریس ویژگیها بزرگ است. مگر اینکه تعداد زیادی از کلمات را حذف کنیم که عملاً دیتاست ناقص و بهدردنخور خواهد شد.
از طرفی sparse و خلوت بودن یکی از معایب CountVectorizer بود که تعداد زیادی درایهی صفر داشتیم. Tf-idf کمی به تعدیل این محدودیت کمک کرد ولی نتوانست بهطورکلی آن را ریشهکن کند.
پس در قسمتهای بعدی این مجموعهی آموزشی، یاد میگیریم تکنیک word embedding چیست. هدف اصلی این تکنیک حل محدودیتهای اشاره شده در بردارسازی متن است. در word embedding بهازای هر کلمه یک بردار عددی با طول ثابت و محدود ایجاد میشود که از مثالهای معروف آن میتوان به GloVe،Word2vec و fastText اشاره کرد. این تکنیکها، به متن و corpus وابسته نیستند. این ویژگی، یک وجه تمایز مهم در مقایسه با سایر تکنیکها است! که لزوماً چیز خوبی نیست چون گاهی باید به context هم توجه کرد. به همین دلیل مدلی مثل Bert متولد شد.
مفهوم پیشرفتهتر: آشنایی با ماتریس Term-Term
اگر ماتریس document-term، مبتنی بر CountVectorizer یا tf-idf باشد، مفهوم (context) کلمه را در نظر نمیگیرد. پس برای جبران این محدودیت، از ماتریس هم رخدادی (co-occurrence matrix) استفاده میشود. در این ماتریس هدف، پیداکردن تعداد دفعاتی است که دوکلمه در کنار هم (یا با فاصلهی اندک) مشاهده شده است.
برای ایجاد این ماتریس، از یک پنجره یا window در اطراف کلمه استفاده میکنیم (به طور مثال، خود کلمه را در نظر گرفته و سه کلمه در سمت چپ (قبل آن) و سه کلمه در سمت راست آن (بعد از آن) را نیز لحاظ میکنیم)، در این صورت هر درایه تعداد دفعاتی را که کلمه موردنظر در (3±) کلمه کناری آن استفاده شده است را نشان میدهد.
به طور مثال، این corpus کوتاه را در نظر بگیرید:
sentences = ['ways to replace the noisy Mac keyboard',
'do you prefer Windows or Mac',
'the Mac has a noisy keyboard',
'ways to install Windows on a Mac',
'you need a Windows license to install Windows on a Mac'
]
اگر پنجرهای با اندازه 3 را در نظر بگیریم (سه کلمه از راست و سه کلمه از چپ)، ماتریس هم رخداد term-term زیر را خواهیم داشت:
باتوجهبه اینکه سایز پنجره را 3 در نظر گرفتیم، دو توکن windows و mac سه مرتبه با هم در یک پنجره بودهاند و بهاینترتیب توکن noisy با دو توکن mac و keyboard دومرتبه با هم در یک پنجره بوده اما با توکن windows در هیچ پنجرهای نبوده است.
راههای زیادی برای پیادهسازی ماتریس هم رخداد word-word وجود دارد. هدف این است که بر روی هر متن از corpus حلقه بزنیم و اطراف کلمات، پنجره بسازیم. میتوانید چند نمونه پیادهسازی شده به زبان پایتون را در این صفحه Stack Overflow پیدا کنید.
- مقدار tf-idf score یک عدد اعشاری است که میزان اهمیت یک کلمه را در یک داکیومنت نشان میدهد.
- برای پیادهسازی tf-Idf به کمک کتابخانه scikit-learn میتوانیم از TfidfVectorizer استفاده کنیم. روشهای مختلفی برای محاسبه tf-idf score برای هر کلمه و داکیومنت وجود دارد.
- اگر ماتریس document-term، مبتنی بر Bow یا tf-idf باشد، مفهوم کلمه را در نظر نمیگیرد. پس برای جبران این محدودیت، از ماتریس هم رخدادی استفاده میشود.
در این مقاله فهمیدیم tf-idf چیست وچه محدودیتهایی دارد. تاکنون، ما دو تکنیک بردارسازی که بخشی از تکنیک bag-of-words هستند را بررسی کردیم و بعد از بهدستآوردن بردار عددی کلمات، پروژه text classification را پیادهسازی کردیم. در مقالههای بعدی، بر روی یکی از پروژههای معروف حوزه NLP classification یعنی تحلیل احساسات با پایتون (sentiment analysis) کار میکنیم.