سناریو
دو بردار دارید. ممکن این بردارها بردار های embedding باشند، یا پروفایل کاربر، یا آرایههای پیکسل. باید بدانید: این دو چقدر به هم نزدیک هستند؟
جواب کاملاً به این بستگی دارد که کدام تابع فاصله را انتخاب کنید. دو نقطه از داده میتوانند تحت یک معیار، نزدیکترین همسایه و تحت معیاری دیگر، دور از هم باشند.
هیچ تابع فاصله ی کاملی وجود ندارد. L2 برای دادههای فضایی و مکانی کار میکند. شباهت کسینوسی در NLP حاکم است. ژاکارد برای مجموعهها مناسب است. فاصلهی ویرایش برای رشتهها. ماهالانوبیس همبستگیها را در نظر میگیرد. وازرشتاین جرم احتمال را جابهجا میکند. هر کدام فرض متفاوتی دربارهی معنای «شباهت» در خود جای داده است.
نُرم «اندازه» یک بردار را اندازه میگیرد. (norm measures the size of a vector)
نُرم L1 Norm (Manhattan distance)
نُرم L1 قدر مطلق همه درایهها را جمع میزند.
||x||_1 = |x_1| + |x_2| + ... + |x_n|
به آن فاصله منهتن میگویند چون مسافتی را اندازه میگیرد که در یک شبکه شهری راه میروید و فقط میتوانید در امتداد محورها حرکت کنید – بدون خط مورب.
مثال:
نقطه A = (1, 1)
نقطه B = (4, 5)
فاصله L1 = |4-1| + |5-1| = 3 + 4 = 7
در یک شبکه، ۳ بلوک شرق و ۴ بلوک شمال راه میروید.
چه زمانی از L1 استفاده کنیم:
- دادههای پراکنده با ابعاد بالا (ویژگیهای متنی، one-hot encoding)
- زمانی که میخواهید در برابر نقاط پرت (outliers) مقاوم باشید
- مسائل انتخاب ویژگی (feature selection) زیرا رگولاریزیشن L1 باعث پراکندگی میشه و وزن هایی که مقدار نزدیک به صفر دارند را به صفر تبدیل می کنه.
نُرم L2 (فاصله اقلیدسی) - L2 Norm (Euclidean distance)
نُرم L2 فاصله خط مستقیم است. جذر مجموع مجذور درایهها.
||x||_2 = sqrt(x_1^2 + x_2^2 + ... + x_n^2)
این همان فاصلهای است که در کلاس هندسه یاد گرفتید. قضیه فیثاغورس در ابعاد n.
نقطه A = (1, 1)
نقطه B = (4, 5)
فاصله
L2 = sqrt((4-1)^ 2 + (5-1)^2) = sqrt(9 + 16) = sqrt(25) = 5.0
خط مستقیم که به صورت مورب از شبکه عبور میکند.
چه زمانی از L2 استفاده کنیم:
- دادههای پیوسته با ابعاد کم تا متوسط
- وقتی مقیاس ویژگیها قابل مقایسه است
- فاصلههای فیزیکی (دادههای مکانی، خواندن سنسورها)
- شباهت تصویر در سطح پیکسل
نُرمهای Lp: خانواده عمومی - Lp Norms: the general family
L1 و L2 حالت خاصی از نُرم Lp هستند:
||x||_p = (|x_1|^p + |x_2|^p + ... + |x_n|^p)^(1/p)
مقادیر مختلف p، توپهای واحد با شکلهای متفاوت تولید میکنند (مجموعه نقاطی که فاصله ۱ از مبدأ دارند):
p=1: شکل لوزی (گوشهها روی محورها)
p=2: دایره/کره (توپ گرد معمولی)
p=3: بیضیمانند (چهارگوش گرد)
p=inf: مربع/مکعب (اضلاع تخت در امتداد محورها)
نُرم L-بینهایت (فاصله چبیشف) - L-infinity Norm (Chebyshev distance)
وقتی p به سمت بینهایت میل میکند، نُرم Lp به بزرگترین درایه از لحاظ قدر مطلق همگرا میشود.
||x||_inf = max(|x_1|, |x_2|, ..., |x_n|)
فاصله بین دو نقطه به وسیله یک بعدی تعیین میشود که در آن بیشترین اختلاف را دارند. همه ابعاد دیگر نادیده گرفته میشوند.
نقطه A = (1, 1)
نقطه B = (4, 5)
فاصله L-inf = max(|4-1|, |5-1|) = max(3, 4) = 4
شباهت کسینوسی و فاصله کسینوسی - Cosine Similarity and Cosine Distance
شباهت کسینوسی زاویه بین دو بردار را اندازه میگیرد و اندازه آنها را نادیده میگیرد.
cos_sim(a, b) = (a . b) / (||a||_2 * ||b||_2)
این مقدار از -1 (جهتهای مخالف) تا +1 (جهت یکسان) متغیر است. بردارهای عمود بر هم شباهت کسینوسی ۰ دارند.
فاصله کسینوسی آن را به فاصله تبدیل میکند: فاصله کسینوسی = 1 - شباهت کسینوسی. این مقدار از ۰ (جهت یکسان) تا ۲ (جهت مخالف) متغیر است.
a = (1, 0) b = (1, 1)
cos_sim = (1*1 + 0*1) / (1 * sqrt(2)) = 1/sqrt(2) = 0.707
cos_dist = 1 - 0.707 = 0.293
چرا کسینوس در NLP و Embedding غالب است؟ در متن، طول سند نباید بر شباهت تأثیر بگذارد. سندی در مورد گربهها که دو برابر سند دیگر درباره گربهها بلندتر است، هنوز باید «شبیه» محسوب شود. شباهت کسینوسی اندازه (طول) را نادیده میگیرد و فقط جهت را در نظر میگیرد. دو سند با توزیع کلمات یکسان اما طول متفاوت، در یک جهت قرار دارند و شباهت کسینوسی ۱.۰ میگیرند.
چه زمانی از شباهت کسینوسی استفاده کنیم:
- شباهت متنی (بردارهای TF-IDF، توکارهای کلمه، توکارهای جمله)
- هر حوزهای که اندازه نویز و جهت سیگنال باشد
- سیستمهای توصیهگر (بردارهای ترجیح کاربر)
- جستجوی embedding (پایگاههای داده برداری تقریباً همیشه از کسینوس یا ضرب داخلی استفاده میکنند)
شباهت ضرب داخلی در مقابل شباهت کسینوسی - Dot Product Similarity vs Cosine Similarity
ضرب داخلی دو بردار عبارت است از:
a . b = a_1*b_1 + a_2*b_2 + ... + a_n*b_n = ||a|| ||b|| cos(angle)
شباهت کسینوسی همان ضرب داخلی نرمالیزه شده با هر دو اندازه است. وقتی هر دو بردار قبلاً واحد-نرمال شدهاند (اندازه = ۱)، ضرب داخلی و شباهت کسینوسی یکسان هستند.
If ||a|| = 1 and ||b|| = 1: a . b = cos(angle between a and b)
وقتی اندازهها متفاوت باشند: ضرب داخلی اطلاعات اندازه را هم شامل میشود. بردار با اندازه بزرگتر، نمره ضرب داخلی بالاتری میگیرد. این در برخی سیستمهای بازیابی اهمیت دارد، جایی که میخواهید آیتمهای «محبوب» رتبه بالاتری داشته باشند. اندازه به عنوان یک سیگنال ضمنی کیفیت یا اهمیت عمل میکند.
a = (3, 0) b = (1, 0) c = (0, 1)
dot(a, b) = 3 dot(a, c) = 0
cos(a, b) = 1.0 cos(a, c) = 0.0
در عمل:
- از شباهت کسینوسی استفاده کنید وقتی شباهت جهتی خالص میخواهید
- از ضرب داخلی استفاده کنید وقتی اندازهها حاوی اطلاعات معناداری هستند
- بسیاری از پایگاههای داده برداری (Pinecone, Weaviate, Qdrant) به شما امکان انتخاب بین این دو را میدهند.
با تشکر