Naive Bayes یک خانواده طبقهبند است که از قضیه بیز و فرض استقلال شرطی ویژگیها با دانستن کلاس استفاده میکند. در نسخه چندجملهای برای متن، تعداد رخداد واژهها میتواند ویژگی باشد. اینجا چهار پیام فارسی ساختگی را میشماریم و تصمیم مدل برای یک پیام را تا آخر محاسبه میکنیم؛ هیچ مدل آماده یا API در کار نیست.
داده و واژهنامه از کجا میآیند؟
| کلاس | دو پیام آموزشی |
|---|---|
| پشتیبانی | «خطا ورود» و «خطا سامانه» |
| فروش | «قیمت خرید» و «قیمت فروش» |
واژهنامه شش عضو دارد: خطا، ورود، سامانه، قیمت، خرید و فروش. در کلاس پشتیبانی، خطا دو بار و دو واژه دیگر هرکدام یک بار آمدهاند. در فروش هم قیمت دو بار و خرید و فروش هرکدام یک بار هستند. هر کلاس چهار رخداد واژه و دو سند دارد؛ پیشین هر کلاس با نسبت اسناد آموزشی برابر ۰٫۵ است.
این تمرین از split ساده روی فاصله استفاده میکند. نیمفاصله، نشانهگذاری، صورتهای متفاوت ی و ک یا نفی را حل نکردهایم. همین انتخاب پیشپردازش بخشی از تعریف مدل است؛ تغییرش پس از آموزش باید همراه بازسازی واژهنامه و آزمون باشد.
هموارسازی مانع صفرشدن یک احتمال میشود
با هموارسازی لاپلاس و α=۱، احتمال واژه در کلاس برابر «تعداد آن واژه +۱» تقسیم بر «مجموع رخداد واژههای کلاس + تعداد اعضای واژهنامه» است. مخرج اینجا ۴+۶=۱۰ است. پس احتمال خطا در پشتیبانی ۳÷۱۰ و احتمال ورود ۲÷۱۰ میشود. در فروش هر دو واژه در آموزش آن کلاس صفر بار آمدهاند، اما احتمال هموارشده هرکدام ۱÷۱۰ است.
برای پیام «خطا ورود»، امتیاز نامقیاسشده پشتیبانی ۰٫۵×۰٫۳×۰٫۲=۰٫۰۳ و فروش ۰٫۵×۰٫۱×۰٫۱=۰٫۰۰۵ است. نرمالکردن این دو امتیاز، سهم پشتیبانی را ۶÷۷ یعنی حدود ۰٫۸۵۷۱۴۳ میدهد. این احتمال در مدل کوچک فرضی است؛ نه تضمین درستی این پیام در دنیای واقعی و نه درصد دقت کلی سامانه.
کد کوتاه با محاسبه در فضای لگاریتم
from collections import Counter
import math
corpus = {'support': ['خطا ورود', 'خطا سامانه'],
'sales': ['قیمت خرید', 'قیمت فروش']}
counts = {c: Counter(' '.join(docs).split()) for c, docs in corpus.items()}
vocab = set().union(*(set(v) for v in counts.values()))
ndocs = sum(len(docs) for docs in corpus.values())
alpha = 1.0
def predict(text):
terms = [t for t in text.split() if t in vocab]
if not terms:
return None, {}
scores = {}
for c in corpus:
prior = len(corpus[c])/ndocs
denom = sum(counts[c].values())+alpha*len(vocab)
scores[c] = math.log(prior)+sum(
math.log((counts[c][t]+alpha)/denom) for t in terms)
top = max(scores.values())
weights = {c: math.exp(s-top) for c, s in scores.items()}
total = sum(weights.values())
probs = {c: z/total for c, z in weights.items()}
return max(probs, key=probs.get), probs
label, probs = predict('خطا ورود')
print('vocabulary size', len(vocab))
print(label, {c: round(v, 6) for c, v in probs.items()})
assert len(vocab) == 6 and label == 'support'
assert abs(probs['support']-6/7) < 1e-12
assert predict('ناشناخته')[0] is Noneجمع لگاریتمها جای ضرب احتمالهای کوچک را میگیرد. برای نرمالسازی نیز بیشترین امتیاز از همه کم میشود تا محاسبه مناسبتری داشته باشیم. واژه بیرون واژهنامه در این نسخه نادیده گرفته میشود؛ اگر هیچ واژه شناختهشده باقی نماند، تابع عمداً تصمیم نمیدهد. در غیر این صورت حتی یک واژه شناختهشده میتواند خروجی بسازد؛ این به معنی کافیبودن شاهد برای اقدام خودکار نیست.
از چهار پیام چه نتیجهای نمیتوان گرفت؟
فرض استقلال، ساختار کامل زبان را بازنمایی نمیکند. متنهایی با همان واژهها و ترتیب متفاوت در این نمایش شمارشی میتوانند ورودی یکسان داشته باشند. برای تمرین، «ورود خطا» را وارد کنید و همان خروجی را ببینید. سپس یک واژه ناموجود اضافه کنید و بررسی کنید چرا در این نسخه اثری ندارد.
برای ارزیابی، مجموعه جدا، برچسبهای روشن و پیامهای مرزی یا خارج از دامنه لازم است. امتیاز احتمالی را هم باید جداگانه بررسی کرد؛ راهنمای کالیبراسیون توضیح میدهد چرا مقدار بزرگتر لزوماً فراوانی واقعی متناظر نیست. مقایسه یادگیری نظارتشده و بدون نظارت هم نقش پاسخ مرجع را روشن میکند.
اتصال به یک نیاز عملی
اگر هدف ارجاع درخواست مشتری است، ابتدا نمونههایی از هر دسته و مسیر انسانی برای متن مبهم آماده کنید. در بررسی راهکارهای اپرا همین تعریف مسئله مفید است؛ کد این راهنما، سامانه آماده ارجاع مشتری یا توصیف فناوری داخلی اپرا نیست.
فایل تمرین و منابع
دریافت کد کامل این تمرین؛ این فایل فقط از کتابخانه استاندارد پایتون استفاده میکند. ورودیهای آن ساختگی و برای بازتولید محاسبهاند؛ اجرای آموزشی آن نتیجه یک محصول یا مشتری را نشان نمیدهد.
تاریخ بررسی منابع: ۳ نوامبر ۲۰۲۶. منابع، مرجع روشاند؛ دادهها، اعداد و کد مثال برای همین راهنما طراحی شدهاند.
ادامه مسیر یادگیری
رگرسیون لجستیک و سیگموید — برای دیدن یک سازوکار متفاوت ساخت احتمال کلاس، مثال رگرسیون لجستیک را مطالعه کنید؛ این دو مثال بنچمارک مقایسه کیفیت نیستند.