Case 2. Why Euclidean distance is worse than cosine similarity

Comparing Euclidean distance and cosine similarity on the same vectors

In this case, we compare Euclidean distance and cosine similarity on exactly the same vectors. You will see that Euclidean distance is sensitive to vector magnitude, while cosine similarity preserves semantic closeness even when one vector is a scaled version of another.

Example of code:

 
<?php

$documents 
= [
    [
        
'title' => 'Email campaign optimization',
        
'embedding' => [0.100.840.290.580.69],
    ],
    [
        
'title' => 'Scaling PHP workers',
        
'embedding' => [0.110.810.360.630.72],
    ],
    [
        
'title' => 'Monitoring email delivery',
        
'embedding' => [0.090.910.280.570.74],
    ],
    
// Same meaning, but different scale
    
[
        
'title' => 'Scaled email embedding',
        
'embedding' => [1.08.42.95.86.9],
    ],
    [
        
'title' => 'How to make coffee',
        
'embedding' => [0.910.040.150.080.02],
    ],
];

function 
euclideanDistance(array $a, array $b): float {
    
$sum 0.0;

    foreach (
$a as $i => $value) {
        
$sum += ($value $b[$i]) ** 2;
    }

    return 
sqrt($sum);
}

function 
cosineSimilarity(array $a, array $b): float {
    
$dotProduct 0.0;
    
$normA 0.0;
    
$normB 0.0;

    foreach (
$a as $i => $value) {
        
$dotProduct += $value $b[$i];
        
$normA += $value ** 2;
        
$normB += $b[$i] ** 2;
    }

    if (
$normA == 0.0 || $normB == 0.0) {
        return 
0.0;
    }

    return 
$dotProduct / (sqrt($normA) * sqrt($normB));
}