Kosinüs benzerliği, iki vektörün yönlerinin ne kadar aynı olduğunu ölçer. NumPy ile iki vektörün noktasal çarpımını normlarının çarpımına bölerek hesaplayabilirsiniz:
Kosinüs benzerliği şu formülle hesaplanır:
Burada
Aşağıdaki varsayımsal örnekte iki belge, üç özellikten oluşan vektörlerle gösteriliyor:
Bu kodun çıktısı yaklaşık olarak
Aynı hesabı tek satırda da yazabilirsiniz:
Kosinüs benzerliği, değerlerin büyüklüğünden çok vektörlerin yönünü karşılaştırır. Bu nedenle bir vektörün tüm elemanlarını aynı katsayıyla artırmak benzerliği değiştirmeyebilir.
Vektörlerden biri yalnızca sıfırlardan oluşuyorsa normu sıfır olur ve formülde sıfıra bölme gerçekleşir. Bu durumda kosinüs benzerliği tanımsızdır; sonucu zorla
Fonksiyon, önce iki girdinin aynı boyutta olduğunu denetler, ardından sıfır vektörünü engeller. Boyutlar farklıysa veya girdilerden biri sıfır vektörüyse hesaplamayı sürdürmek yerine açık bir hata verir. Böylece hatalı bir benzerlik değeriyle sonraki sıralama ya da eşleştirme işlemlerine devam etmezsiniz.
Belge, ürün veya kullanıcı vektörlerini bir matrisin satırları olarak tutuyorsanız, her satırın normunu ayrı hesaplayıp matris çarpımı kullanabilirsiniz:
Bu örnekte ilk satırın benzerliği
Vektörlerin boyutlarının aynı olması, sayıların aynı ölçüm veya özellik sırasını temsil etmesini de gerektirir. Örneğin bir vektördeki ilk eleman kelime sıklığını, diğerindeki ilk eleman fiyatı temsil ediyorsa boyutlar aynı olsa bile kosinüs benzerliği anlamlı bir karşılaştırma yapmaz.
np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)). Sonuç 1 ise yönler aynı, 0 ise vektörler dik, -1 ise yönler zıttır.Temel hesaplama
Kosinüs benzerliği şu formülle hesaplanır:
cos(θ) = (A · B) / (||A|| × ||B||)Burada
A · B noktasal çarpımı, ||A|| ve ||B|| ise vektörlerin Öklid normunu ifade eder. NumPy'de noktasal çarpım için np.dot(), norm için np.linalg.norm() kullanılır.İki vektör için çalışan örnek
Aşağıdaki varsayımsal örnekte iki belge, üç özellikten oluşan vektörlerle gösteriliyor:
Python:
import numpy as np
ilk_vektor = np.array([1, 2, 3], dtype=float)
ikinci_vektor = np.array([2, 4, 6], dtype=float)
pay = np.dot(ilk_vektor, ikinci_vektor)
payda = np.linalg.norm(ilk_vektor) * np.linalg.norm(ikinci_vektor)
benzerlik = pay / payda
print(benzerlik)
Bu kodun çıktısı yaklaşık olarak
1.0 olur. İkinci vektör, birincinin pozitif katsayıyla ölçeklenmiş hâli olduğu için yönleri aynıdır. Değerin 1 olması, vektörlerin elemanlarının birebir aynı olduğunu değil, yönlerinin aynı olduğunu gösterir.Aynı hesabı tek satırda da yazabilirsiniz:
Python:
import numpy as np
a = np.array([1, 2, 3], dtype=float)
b = np.array([2, 4, 6], dtype=float)
benzerlik = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(benzerlik)
Sonucun nasıl yorumlanacağı
Kosinüs benzerliği, değerlerin büyüklüğünden çok vektörlerin yönünü karşılaştırır. Bu nedenle bir vektörün tüm elemanlarını aynı katsayıyla artırmak benzerliği değiştirmeyebilir.
- 1'e yakın değer: Vektörler benzer yöndedir. Metin gömme vektörlerinde bu genellikle benzer içerik veya anlam yönelimi olarak yorumlanır; tek başına kesin bir anlamsal eşleşme kanıtı değildir.
- 0'a yakın değer: Vektörler birbirine dik veya büyük ölçüde ilgisiz yönlerdedir. Bu, uygulamadaki özelliklerin gerçekten bağımsız olduğunu kesin olarak kanıtlamaz.
- -1'e yakın değer: Vektörler zıt yöndedir. Sonucun negatif değer alıp alamayacağı, kullandığınız veri ve modelin vektör uzayına bağlıdır.
[1, 0] ile [0, 1] için sonuç 0 olur; çünkü noktasal çarpımları sıfırdır. [1, 0] ile [-1, 0] için sonuç -1 olur; çünkü yönleri tamamen zıttır.Sıfır vektörünü kontrol etme
Vektörlerden biri yalnızca sıfırlardan oluşuyorsa normu sıfır olur ve formülde sıfıra bölme gerçekleşir. Bu durumda kosinüs benzerliği tanımsızdır; sonucu zorla
0 yapmak matematiksel olarak doğru bir benzerlik hesabı değildir.
Python:
import numpy as np
def kosinus_benzerligi(a, b):
a = np.asarray(a, dtype=float)
b = np.asarray(b, dtype=float)
if a.shape != b.shape:
raise ValueError("Vektörlerin boyutları aynı olmalıdır.")
a_norm = np.linalg.norm(a)
b_norm = np.linalg.norm(b)
if a_norm == 0 or b_norm == 0:
raise ValueError("Sıfır vektörü için kosinüs benzerliği tanımsızdır.")
return np.dot(a, b) / (a_norm * b_norm)
print(kosinus_benzerligi([1, 2, 3], [2, 4, 6]))
Fonksiyon, önce iki girdinin aynı boyutta olduğunu denetler, ardından sıfır vektörünü engeller. Boyutlar farklıysa veya girdilerden biri sıfır vektörüyse hesaplamayı sürdürmek yerine açık bir hata verir. Böylece hatalı bir benzerlik değeriyle sonraki sıralama ya da eşleştirme işlemlerine devam etmezsiniz.
Birden çok vektörü tek vektörle karşılaştırma
Belge, ürün veya kullanıcı vektörlerini bir matrisin satırları olarak tutuyorsanız, her satırın normunu ayrı hesaplayıp matris çarpımı kullanabilirsiniz:
Python:
import numpy as np
sorgu = np.array([1, 2, 3], dtype=float)
vektorler = np.array([
[1, 2, 3],
[3, 2, 1],
[0, 0, 0]
], dtype=float)
sorgu_normu = np.linalg.norm(sorgu)
vektor_normlari = np.linalg.norm(vektorler, axis=1)
paylar = vektorler @ sorgu
paydalar = vektor_normlari * sorgu_normu
benzerlikler = np.full(len(vektorler), np.nan)
gecerli = paydalar != 0
benzerlikler[gecerli] = paylar[gecerli] / paydalar[gecerli]
print(benzerlikler)
Bu örnekte ilk satırın benzerliği
1'e eşit olur. İkinci satırın sonucu daha düşük çıkar; çünkü yönü sorgu vektörüyle aynı değildir. Üçüncü satır sıfır vektörü olduğu için sonucu nan bırakılır. Gerçek uygulamada bu satırı karşılaştırmadan önce kaldırabilir veya ayrı bir geçersiz veri durumu olarak işleyebilirsiniz.Vektörlerin boyutlarının aynı olması, sayıların aynı ölçüm veya özellik sırasını temsil etmesini de gerektirir. Örneğin bir vektördeki ilk eleman kelime sıklığını, diğerindeki ilk eleman fiyatı temsil ediyorsa boyutlar aynı olsa bile kosinüs benzerliği anlamlı bir karşılaştırma yapmaz.