The geometry behind the dot product: projections and unit vectors

Dot Product Geometry is the part most developers skip. In 14 years of building systems I have watched plenty of them treat machine learning libraries as black boxes: pipe the data in, take the similarity score out, ship it. Then the recommendation engine starts feeling off once the dataset gets messy, and nobody can say why.

Guessing works until it doesn’t. If you are building search relevance or product recommendations, the math is the part you cannot skip, and machine learning project stability leans on it as much as on your tooling. That means knowing what unit vectors and projections say about the relationship between two data points.

Unit vectors strip out the noise

A unit vector is a vector with a magnitude of 1. Normalizing one is a way of saying you don’t care how big it is, only which way it points. That distinction matters in production, because magnitude is often just noise, the user who clicks on everything, while direction is closer to intent.

You normalize a non-zero vector by dividing it by its magnitude, which splits it into direction and size. Compare two unit vectors after that and the angle between them is a clean similarity score: 1 when they point the same way, -1 when they point opposite.

Scalar projection is a shadow

Scalar projection answers one question: how much of vector A lies along the direction of vector B? I tell junior devs to picture a shadow. Hold a stick, that is vector A, and shine a light straight down onto the ground, which is the direction of vector B. The length of the shadow on the ground is your scalar projection.

In Dot Product Geometry that shadow works out to the magnitude of A multiplied by the cosine of the angle between the two vectors, which makes it the plainest measure of directional alignment there is. At 90 degrees the shadow disappears and the similarity is zero.

Implementing dot product geometry in PHP

Python does the heavy lifting for most of us, but every so often the similarity logic has to live in the WordPress backend, say for a lightweight related posts feature. Here is the dot product and cosine similarity with no library behind them.

<?php
/**
 * Calculate the Dot Product of two vectors.
 * 
 * @param array $vecA
 * @param array $vecB
 * @return float
 */
function bbioon_calculate_dot_product(array $vecA, array $vecB) {
    if (count($vecA) !== count($vecB)) {
        throw new Exception("Vectors must be of equal length.");
    }
    
    $product = 0;
    foreach ($vecA as $index => $value) {
        $product += $value * $vecB[$index];
    }
    return (float) $product;
}

/**
 * Calculate Cosine Similarity.
 * Grounded in Dot Product Geometry.
 */
function bbioon_cosine_similarity(array $vecA, array $vecB) {
    $dotProduct = bbioon_calculate_dot_product($vecA, $vecB);
    
    $magA = sqrt(array_sum(array_map(fn($x) => $x * $x, $vecA)));
    $magB = sqrt(array_sum(array_map(fn($x) => $x * $x, $vecB)));
    
    if ($magA == 0 || $magB == 0) return 0.0;
    
    return $dotProduct / ($magA * $magB);
}

Vector projection tells you where, not just how far

Scalar projection hands you a number, the how far. Vector projection hands you the actual coordinates on the trail. You want that when a vector has to be broken into components, for instance when you are filtering specific attributes out of a multi-dimensional user profile.

Vector projection is the scalar projection multiplied by the unit vector of whichever direction you are projecting onto. If you want to go deeper, the Wikipedia entry on Dot Products holds up well, and the thread on Math StackExchange has some good intuition from people who explain it better than I do.

If this dot product geometry work is eating your dev hours, I can take it on. I have been wrestling with WordPress and custom algorithm implementations since the 4.x days.

The practical version

None of this turns you into a math genius, and it doesn’t need to. Dot Product Geometry is how you make the behavior predictable. Once you know what shadow your data casts, the recommendation engine stops being a box you hope is working and becomes something you can debug.

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.