TF-IDF روشی برای نمایش عددی متن است که فراوانی واژه در یک سند را با میزان حضورش در مجموعهٔ اسناد ترکیب میکند. در یک قرارداد متداول، واژهای که در اسناد کمتری دیده میشود وزن بیشتری میگیرد. این وزن، میزان اهمیت مطلق واژه یا فهم معنای جمله نیست؛ به مجموعه و روش آمادهسازی وابسته است.
سه سند کوچک برای کنترل دستی
متنهای ساختگی ما «تماس مشتری تماس»، «مشتری پاسخ» و «پاسخ سریع» هستند. جداکردن واژه با فاصله برای همین دادهٔ کنترلشده کافی است؛ این قاعده را توکنایزر کامل فارسی نمینامیم. واژهٔ «تماس» دو بار در سند اول آمده اما فقط در یک سند حضور دارد. پس tf آن در سند اول ۲ و df آن در کل مجموعه ۱ است.
در قرارداد هموارشدهٔ این تمرین، idf برابر log((۱+n)/(۱+df))+۱ است؛ log لگاریتم طبیعی است. با سه سند، idf تماس و سریع حدود ۱٫۶۹۳۱۴۷ میشود و idf مشتری و پاسخ حدود ۱٫۲۸۷۶۸۲ است. وجود دو بار «تماس» در یک سند، df را ۲ نمیکند؛ هر سند فقط یک بار در این شمارش سهم دارد.
| واژه | df | idf هموارشده | وزن خام در سند اول |
|---|---|---|---|
| تماس | ۱ | حدود ۱٫۶۹۳۱ | حدود ۳٫۳۸۶۳ |
| مشتری | ۲ | حدود ۱٫۲۸۷۷ | حدود ۱٫۲۸۷۷ |
| پاسخ | ۲ | حدود ۱٫۲۸۷۷ | ۰ |
| سریع | ۱ | حدود ۱٫۶۹۳۱ | ۰ |
از وزن خام تا بردار واحد
from collections import Counter
import math
docs=['تماس مشتری تماس','مشتری پاسخ','پاسخ سریع']
counts=[Counter(d.split()) for d in docs]
vocabulary=sorted(set().union(*(set(c) for c in counts)))
df={t:sum(t in c for c in counts) for t in vocabulary}
idf={t:math.log((1+len(docs))/(1+df[t]))+1 for t in vocabulary}
def transform(text):
c=Counter(text.split());row=[c[t]*idf[t] for t in vocabulary]
norm=math.sqrt(sum(x*x for x in row))
return [x/norm for x in row] if norm else row
print('vocabulary',vocabulary,'df',df,'idf',idf)
for d in docs:print(d,transform(d))
assert df['تماس']==1 and counts[0]['تماس']==2
assert abs(idf['تماس']-(math.log(2)+1))<1e-12
assert abs(sum(x*x for x in transform(docs[0]))-1)<1e-12
assert transform('واژه_تازه')==[0.]*len(vocabulary)
برای نرمالسازی L2 هر ردیف را بر ریشهٔ مجموع مربع وزنهای همان ردیف تقسیم میکنیم. سند اول تقریباً به وزن ۰٫۹۳۵ برای تماس و ۰٫۳۵۵ برای مشتری میرسد. این مرحله طول بردار را یک میکند؛ تعداد واژهها یا احتمال تعلق متن به یک کلاس را تولید نمیکند.
واژهنامه و آمار از کجا میآیند؟
اگر این نمایش ورودی یک مدل است، واژهنامه و idf را از مجموعهٔ آموزش همان تقسیم بسازید و برای متن تازه نگه دارید. ساختن دوبارهٔ آنها با دادهٔ آزمون، مقایسه را تغییر میدهد؛ نشت داده را فقط مسئلهٔ برچسبها ندانید. کد برای واژهٔ تازهای که در واژهنامه نیست ستون جدید نمیسازد؛ آن واژه سهمی در خروجی فعلی ندارد.
در متن واقعی، نیمفاصله، شکل حروف و عبارتهای چندواژهای باید سیاست مشخص داشته باشند. «تماس مشتری» ممکن است یک ترکیب مهم باشد که نمایش تکواژهای آن را جدا میکند. توکن مدل زبانی نیز مفهوم دیگری است؛ شمارش این واژهها صورتحساب توکن یک مدل را نمیدهد.
این نمایش کجا کافی نیست؟
دو جمله با واژههای مشابه و ترتیب متفاوت ممکن است معنی مخالف بدهند. همچنین واژهٔ نادر میتواند غلط املایی باشد. برای جستوجوی راهنما یا دستهبندی درخواست، خروجی را با نمونهٔ مرجع و یک خط مبنای ثابت بسنجید؛ از بزرگبودن یک وزن، کیفیت پاسخ مشتری را نتیجه نگیرید. برای استفادهٔ عملی از محتوای معتبر در پاسخگویی، مسیر مناسب خدمات اپرا را ببینید؛ این مثال ادعای استفادهٔ محصول از الگوریتم خاصی ندارد.
فایل تمرین و منابع
دریافت کد مستقل این راهنما. دادهها ساختگی و آموزشیاند؛ کد اتصال شبکه، فایل شخصی یا فراخوانی سرویس ندارد.
تاریخ مطالعهٔ منبع: ۳ نوامبر ۲۰۲۶. محاسبهها و مثال این مطلب برای آموزش طراحی شدهاند.