آموزش هوش مصنوعی

در جست‌وجوی فارسی، هر تفاوتی را حذف نکنید

نرمال‌سازی یونیکد، «ی» و «ک» عربی و فارسی را یکی نمی‌کند. برای نیم‌فاصله، رقم‌ها و شناسه‌ها قاعده جدا بنویسید و هم نتیجه‌های جاافتاده، هم تطبیق‌های اشتباه را بسنجید.

در جست‌وجوی فارسی، هر تفاوتی را حذف نکنید
نویسنده
تیم ژرف
انتشار
۴ مهر ۱۴۰۵
زمان مطالعه
۱۲ دقیقه

کارشناس پشتیبانی «پیگیری» را جست‌وجو می‌کند، اما سامانه نامه‌ای با واژه «پيگيري» را پیدا نمی‌کند. تیم فنی نرمال‌سازی یونیکد را فعال کرده و انتظار دارد مشکل حل شده باشد. نشده است. حالا پیشنهاد می‌شود همه تفاوت‌های ظاهری را حذف کنند؛ پیشنهادی که اگر به شناسه پرونده هم برسد، شاید دو مقدار متمایز را یکی کند.

این موقعیت فرضی است. تصمیم واقعی برای سازنده جست‌وجوی سازمانی یا دستیار متصل به اسناد این است: کدام تفاوت را در کدام فیلد نادیده بگیریم؟ پاسخ، یک دستور عمومی «تمیزکردن متن» نیست. باید قاعده تطبیق را نوشت، روی جفت‌های مشخص آزمود و روشن کرد که تطبیق برای پیدا‌کردن سند است یا برای تشخیص یک شناسه.

شش جفت نویسه که محدودیت نرمال‌سازی را نشان می‌دهند

در پیوست ۱۵ استاندارد یونیکد، NFC بر هم‌ارزی کانونی تکیه دارد؛ NFKC تبدیل‌های سازگاری را هم اضافه می‌کند. هیچ‌کدام نام دیگر «اصلاح نگارش فارسی» نیست. برای دیدن تفاوت، جدول زیر را با مقایسه خروجی String.normalize در جاوااسکریپت ساختیم. «برابر» یعنی دو رشته پس از اعمال همان روش، دقیقاً یک توالی نویسه دارند؛ نه اینکه دو شخص، سند یا مفهوم یکسان‌اند.

دو ورودیپس از NFCپس از NFKC
کاف عربی U+0643 و کاف فارسی U+06A9متفاوتمتفاوت
یای عربی U+064A و یای فارسی U+06CCمتفاوتمتفاوت
رقم ١ با کد U+0661 و ۱ با کد U+06F1متفاوتمتفاوت
① با کد U+2460 و رقم لاتین 1متفاوتبرابر
a به‌علاوه علامت U+0301 و نویسه آماده áبرابربرابر
«می‌رود» با U+200C و «می رود» با فاصله معمولیمتفاوتمتفاوت

این‌ها شش آزمون کوچک‌اند، نه سنجش کیفیت یک موتور جست‌وجو. آن‌ها را با Node.js 25.6.1، داده یونیکد 17.0 و ICU 78.2 اجرا کردیم؛ مرجع استاندارد بررسی‌شده، نسخه 18.0 است. رفتار این جفت‌های قدیمی را در محیط خود نیز ثبت کنید. عنوان «پشتیبانی از یونیکد» به‌تنهایی نتیجه آزمون شما را مشخص نمی‌کند.

نتیجه عملی روشن است: انتخاب NFKC به‌جای NFC، جایگزین قاعده تبدیل «ي» به «ی» نیست. در مقابل، همین انتخاب می‌تواند تمایزی مثل دایره دور رقم را از بین ببرد. پس «قوی‌تر» نام مناسبی برای «مناسب‌تر» نیست.

اول مشخص کنید «برابر» برای چه کاری است

در جست‌وجوی عنوان نامه، احتمالاً می‌خواهیم دو شکل «پیگیری» به یک مجموعه نتیجه برسند. در بررسی شناسه‌ای که سامانه دیگری صادر کرده، حق نداریم چنین تصمیمی را خودسرانه بگیریم. قرارداد صادرکننده تعیین می‌کند چه نویسه‌ها و چه تبدیل‌هایی مجازند. حتی اگر دو شناسه در قلم فعلی شبیه دیده شوند، شباهت، مجوز ادغام نیست.

پیش‌نویس تطبیق رشته در W3C توضیح می‌دهد که رشته‌های هم‌شکل، حتی پس از نرمال‌سازی، لزوماً کدهای یکسان ندارند. این سند در زمان بررسی، پیش‌نویس کاری است، نه توصیه‌نامه نهایی. نکته کاربردی برای ما این است که ظاهر صفحه را جای قرارداد مقایسه ننشانیم.

برای هر فیلد، یک تصمیم قابل آزمون بنویسید:

فیلد و کاربردقاعده پیشنهادی برای بررسیچیزی که از تطبیق نتیجه نمی‌شود
عنوان یا متن فارسی برای یافتن سندتبدیل‌های زبانی صریح در نسخه جست‌وجودو سند، یک سند هستند
نام شخص برای پیشنهاد پرونده‌های مرتبطتطبیق گسترده‌تر با نمایش اصل نامدو پرونده متعلق به یک نفرند
شناسه بیرونی یا نام کاربریفقط قاعده مصوب همان فضای شناسهقاعده جست‌وجوی متن برای آن مجاز است
نقل‌قول یا متن شاهدارجاع به نسخه اصلی و محل دقیق آنمتن تبدیل‌شده همان نقل‌قول اصلی است

این جدول پیشنهاد طراحی ژرف است. مسئول هر فیلد باید آن را با کاربرد واقعی سازگار کند. راهنمای پیشین فارسی‌سازی سامانه‌های هوش مصنوعی مسئله زبان و نمایش را گسترده‌تر بررسی می‌کند؛ موضوع اینجا آزمودن همین قرارداد محدودِ تطبیق است.

نیم‌فاصله را حذف‌کردن با فاصله‌گذاشتن فرق دارد

دو تبدیل ساده روی «می‌رود» انجام دهید. حذف U+200C، رشته «میرود» را می‌سازد. جایگزینی آن با فاصله معمولی، «می رود» می‌دهد. این دو خروجی یکسان نیستند و ورودی متفاوتی به مرحله جداکردن واژه‌ها می‌رسانند. اینکه در پایان به نتیجه مشابه برسند، به بقیه زنجیره پردازش بستگی دارد.

در نمونه رسمی تحلیلگر فارسی Elasticsearch، نیم‌فاصله پیش از واژه‌بندی به فاصله معمولی تبدیل می‌شود. پس از آن، فیلترهایی برای رقم‌ها، نرمال‌سازی عربی و فارسی، واژه‌های توقف و ریشه‌یابی می‌آیند. این تنظیم مستندِ یک تحلیلگر است؛ نباید آن را قاعده ذخیره‌سازی تمام فیلدهای فارسی دانست.

برای فیلد واقعی، خروجی مرحله‌ها را ببینید: نویسه‌های پس از تبدیل، توکن‌ها، موقعیت آن‌ها و نتیجه جست‌وجوی عبارت. آزمون یک واژه کوتاه کافی نیست. ممکن است حذف یا جداسازی نیم‌فاصله در عبارت چندواژه‌ای، شرط مجاورت را تغییر دهد. تنظیم نمایه و پرس‌وجو را با هم آزمایش کنید؛ نام یکسانِ تحلیلگر در دو محیط، تضمین یکسان‌بودن تنظیمات نیست.

همه نویسه‌های نامرئی را هم با یک عبارت منظم حذف نکنید. ابتدا نوع نویسه و علت حضورش را تشخیص دهید. کنترل جهت متن، نیم‌فاصله و فاصله معمولی یک نقش ندارند. قاعده محدود و مستند، از فرمان مبهم «همه فاصله‌ها را پاک کن» قابل‌دفاع‌تر است.

خط مشترک، زبان مشترک نمی‌سازد

یک مخزن سازمانی ممکن است متن فارسی، عربی، نام‌های محلی و کد کالا را کنار هم داشته باشد. تبدیل مناسب برای عنوان فارسی را نباید فقط به دلیل شکل حروف، روی همه آن‌ها اجرا کرد. زبان اعلام‌شده فیلد، زبان محتوا و اطمینان به این برچسب را جدا نگه دارید؛ متن بی‌برچسب هم باید مسیر مشخصی داشته باشد.

پژوهش نرمال‌سازی نوشتاری خط فارسی‌عربی نوشته دکتر و همکاران، تنوع این خط و نویسه‌های ظاهراً مشابه اما ناهم‌ارز را بررسی کرده است. مطالعه، هشت زبان و وظایف زبانی مشخص را پوشش می‌دهد. از آن نمی‌توان نتیجه گرفت که یک نگاشت عمومی، کیفیت جست‌وجوی هر سازمان فارسی‌زبان را بهتر می‌کند.

در پیشنهاد ما، هر مجموعه قاعده نام و نسخه دارد؛ مثلاً نسخه مشخصی برای عنوان فارسی، نه تابعی سراسری به نام «پاک‌سازی». فهرست تبدیل‌ها، ترتیب اجرا، سیاست نیم‌فاصله، رقم‌ها و واژه‌بندی بخشی از همان نسخه‌اند. اگر انتخاب قاعده به تشخیص خودکار زبان وابسته است، خروجی آن تشخیص و حالت تردید را هم آزمایش کنید.

یک مدل زبانی نباید در هر درخواست، قانون تازه‌ای برای مشابه‌بودن رشته‌ها اختراع کند. توضیح‌دادن تفاوت به کاربر کار مناسبی برای دستیار است؛ تصمیم تکرارپذیر درباره تبدیل نویسه‌ها را به کد و پیکربندی نسخه‌دار بسپارید.

دو عنوان شبیه، همچنان دو سندند

یک مجموعه ساختگی شامل دو سند با شناسه‌های پایدار متفاوت بسازید. عنوان اول «نامه ۱۲» و عنوان دوم «نامه 12» است. اگر قاعده جست‌وجوی عنوان، رقم فارسی را به لاتین تبدیل کند، هر دو عنوان به یک کلید می‌رسند. این برخورد لزوماً خطا نیست: کاربر ممکن است انتظار داشته باشد با هر دو شیوه نوشتن، هر دو سند را ببیند.

خطا از جایی شروع می‌شود که برنامه کلید مشتق‌شده را شناسه یکتای سند کند. در آن صورت ممکن است یکی جای دیگری را بگیرد یا نتیجه‌ها به‌اشتباه یک مورد شمرده شوند. رابطه لازم برای جست‌وجو، «یک کلید به چند شناسه سند» است؛ حذف تکرار بر اساس شناسه واقعی سند انجام می‌شود، نه متن ساده‌شده عنوان.

مجوز را هم بر همان هویت واقعی بررسی کنید. یکسان‌شدن کلید جست‌وجوی دو سند نباید دامنه دسترسی را عوض کند. اگر دستیار قرار است روی نتیجه اقدامی انجام دهد، باید شناسه انتخاب‌شده را به ابزار بدهد؛ نه عنوانی که پس از تبدیل، دیگر یکتا نیست. اصل هر دو عنوان در نمایش باقی می‌ماند تا کاربر بتواند فرقشان را ببیند.

در راهنمای تطبیق پرونده مشتری، شاهد لازم برای یکی‌دانستن هویت‌ها را جدا بررسی کرده‌ایم. در این مثال، فقط نامزدهای جست‌وجو را گرد آورده‌ایم. بهترشدن یافتن نامزد، مجوز ادغام پرونده نیست.

قاعده پایگاه داده را از تنظیم موتور جست‌وجو جدا بخوانید

گاهی تیم، پردازش متن برنامه را اصلاح می‌کند اما مقایسه در پایگاه داده رفتار دیگری دارد. در مستندات PostgreSQL 18 درباره قواعد مقایسه متن، قواعد غیردترمینیستی می‌توانند رشته‌هایی با بایت‌های متفاوت را برابر بدانند. اینکه کدام تفاوت نادیده گرفته شود، به فراهم‌کننده و تنظیمات بستگی دارد؛ صرف خاموش‌کردن deterministic، دستور نرمال‌سازی فارسی نیست. مستندات همچنین هزینه عملکردی و محدودیت برخی عملیات را گوشزد می‌کند.

از این واقعیت یک آزمون طراحی بیرون می‌آید: مقایسه مستقیم، پیوند جدول‌ها، قید یکتایی، جست‌وجوی دقیق و جست‌وجوی واژگانی را جدا امتحان کنید. لازم نیست همه دقیقاً یک رفتار داشته باشند؛ لازم است تفاوتشان عمدی باشد. سهل‌گیرکردن جست‌وجوی نام نباید بی‌صدا قانون یکتایی شناسه را هم عوض کند.

پیش از تغییر قاعده ستون یا نمایه، گروه مقدارهایی را پیدا کنید که در قاعده جدید برابر می‌شوند. برای هر گروه معلوم کنید برخورد مجاز است، نیاز به بازبینی دارد یا باید تغییر را متوقف کند. درباره نتیجه یک تنظیم پایگاه داده از روی ظاهر رشته‌ها یا آزمایش جاوااسکریپت حکم ندهید. این مقاله PostgreSQL یا Elasticsearch را در محیط عملیاتی آزمایش نکرده است.

آزمون پذیرش به «نباید برابر شوند» هم نیاز دارد

فهرست آزمون را به موارد پیدا‌شده محدود نکنید. یک دسته جفت‌هایی باشد که در فیلد معین باید تطبیق کنند؛ دسته دیگر جفت‌هایی که باید متمایز بمانند. شناسه فیلد، نسخه قاعده، ورودی دقیق، انتظار و دلیل تصمیم را کنار هر جفت ثبت کنید. همان دو رشته می‌توانند در جست‌وجوی عنوان هم‌ارز و در یک فضای شناسه ناهم‌ارز باشند.

نمونه‌های بالا نقطه شروع‌اند: شکل‌های «ک» و «ی»، سه خانواده رقم، نیم‌فاصله در برابر فاصله و نبود فاصله، نویسه ترکیبی و آماده، و رقم محصور در دایره. نمونه‌های واقعیِ مجاز از خطاهای محصول را هم اضافه کنید. اطلاعات شخصی را بی‌دلیل وارد پرونده آزمون نکنید؛ می‌توان شکل خطا را با مقدار ساختگی بازسازی کرد.

برای شناسه‌های حساس، شباهت دیداری را نیز جدا بررسی کنید. استاندارد امنیتی یونیکد ۳۹ اسکلت شباهت را ابزاری برای تشخیص رشته‌های اشتباه‌گرفتنی معرفی می‌کند، نه شکل نرمال‌شده شناسه برای استفاده عمومی. هشدار شباهت نباید خودش دو حساب را یکی کند یا متن کاربر را بازنویسی کند.

علاوه بر انتظار هر جفت، تکرارپذیری را بسنجید: اجرای دوباره همان قاعده، خروجی را تغییر ندهد؛ نمایه‌ساز و مسیر پرس‌وجو با نسخه اعلام‌شده سازگار باشند؛ کلید هر سند به شناسه اصلی برگردد. بی‌تغییربودن اجرای دوم لازم است، ولی کافی نیست. تابعی که همه چیز را به رشته خالی تبدیل کند نیز این آزمون را می‌گذراند!

تغییر قاعده، مهاجرت نمایه است

پیشنهاد اجرایی ما نگهداری منبع قابل ارجاع و ساختن نسخه مشتق‌شده برای جست‌وجوست. نسخه مشتق‌شده، شناسه سند، نسخه منبع، نام فیلد و نسخه قاعده را همراه دارد. اصل محتوا را طبق سیاست دسترسی و نگهداری سازمان حفظ کنید؛ «نگهداری اصل» به معنای انبارکردن دائمی همه داده‌ها نیست.

وقتی قاعده عوض شد، نمایه تازه را از منبع معتبر بسازید، نه از کلیدی که قبلاً بخشی از تفاوت‌ها را از دست داده است. نمایه قدیم و جدید را روی پرسش‌های یکسان مقایسه کنید. تغییرات و حذف‌های هم‌زمان منبع را نیز تا نقطه توافق‌شده برسانید. نمایه تازه‌ای که فقط اسناد قدیمی را خوب می‌یابد، آماده جایگزینی نیست.

نسخه مسیر پرس‌وجو را همراه نسل نمایه انتخاب کنید. جابه‌جایی اشاره‌گر به نمایه تازه، در حالی که پردازش پرسش هنوز قاعده قدیمی دارد، قرارداد را نیمه‌عوض می‌کند. بازگشت هم باید این دو را با هم برگرداند. نتیجه‌های ذخیره‌شده در حافظه نهان را بر اساس نسل مربوط تفکیک یا بی‌اعتبار کنید.

برای دستیارِ نقل‌کننده سند، محل شاهد نیز مهم است. حذف یا تبدیل نویسه ممکن است نشانی کاراکترها را جابه‌جا کند. قطعه جست‌وجو باید به متن اصلی و محل درست آن برگردد؛ متن مشتق‌شده را به‌عنوان نقل‌قول عیناً نمایش ندهید. اگر برگرداندن موقعیت‌ها ممکن نیست، پیش از نقل‌قول دوباره شاهد را در منبع پیدا و بررسی کنید.

نتیجه بیشتر را با نتیجه بهتر اشتباه نگیرید

روی پرسش‌های دارای پاسخ معلوم، سهم اسناد مرتبطِ پیدا‌شده و سهم نتیجه‌های واقعاً مرتبط را جدا بسنجید. برخورد کلیدها را هم گزارش کنید: چند کلید به چند مقدار اصلی یا چند سند رسیده‌اند؟ افزایش این عدد ممکن است مطلوب باشد؛ باید با قاعده فیلد و نمونه‌های بررسی‌شده تفسیر شود، نه اینکه خودکار خطا نام بگیرد.

گزارش را بر اساس نوع تبدیل، منبع ورودی، زبان و فیلد بشکنید. میانگین خوب ممکن است خطای شناسه‌ها را پشت بهبود عنوان‌ها پنهان کند. تأخیر، حجم نمایه، کیفیت رتبه‌بندی و درستی نقل‌قول را کنار پوشش جست‌وجو ببینید. بدون حقیقت مستقل درباره اسناد مرتبط، ادعای نرخ بازیابی واقعی نکنید.

یک مجموعه کوچک از سندهای معلوم و جفت‌های ممنوع را پس از تغییر تحلیلگر، کتابخانه یونیکد، استخراج متن، قلم یا مسیر ورود داده دوباره بررسی کنید. تغییر قلم ممکن است فقط ظاهر را عوض کند؛ همین تفاوت را ثبت کنید تا تیم مشکل نمایشی را با مشکل تطبیق اشتباه نگیرد. گزارش خطا را با کد نویسه و نسخه پردازش غنی کنید، نه با کپی بی‌رویه محتوای محرمانه.

در نهایت، حتی این قرارداد دقیق نیز کامل‌بودن کل مخزن را ثابت نمی‌کند. راهنمای نتیجه خالی جست‌وجو محدودیت دامنه و پایان بررسی را توضیح می‌دهد. اینجا یک مسئله محدود را حل کرده‌ایم: سامانه بداند چه تفاوتی را برای یافتن سند کنار گذاشته و کدام تفاوت را برای تشخیص هویت یا ارائه شاهد، همچنان نگه داشته است.

یادداشت منابع — بررسی‌شده در ۲۶ سپتامبر ۲۰۲۶

جفت‌های آزمون، مجموعه دو‌سندی و پیشنهاد مهاجرت، تحلیل و مثال آموزشی ژرف‌اند؛ نتیجه استقرار مشتری یا آزمون کارایی سرویس نیستند. منابع فنی، رفتار مشخص یا تمایز مفهومی را پشتیبانی می‌کنند، نه تضمین کیفیت جست‌وجوی محصول شما را.

#جست‌وجوی فارسی#نرمال‌سازی یونیکد#بازیابی اطلاعات#کیفیت داده#آزمون نرم‌افزار

مطالب مرتبط

این ابزار را در تیم خودتان راه بیندازید

اگر می‌خواهید ایجنت‌های هوش مصنوعی و اتوماسیون این راهنما را در تیم نرم‌افزار یا فرایندهای سازمان‌تان به کار بگیرید، با یک پایلوت کوچک و قابل اندازه‌گیری شروع کنید.