Imagine you run an e-commerce or content website. A user searches for “holiday gifts”, but your product catalog includes titles like “Christmas stocking”, “December sale”, or “winter celebration bundle”.
A traditional keyword search will struggle to find these items if the exact words don’t match. This is where embeddings come in.
Embeddings let your system search by meaning rather than just matching words. By converting text into numerical vectors that represent semantic meaning, embeddings enable the identification of similar items even when they use different words.
Everyday use cases include:
- Semantic search (searching by meaning)
- Recommendation systems (finding similar products or documents)
- Duplicate detection (different phrasings, same idea)
- Chatbots …
Imagine you run an e-commerce or content website. A user searches for “holiday gifts”, but your product catalog includes titles like “Christmas stocking”, “December sale”, or “winter celebration bundle”.
A traditional keyword search will struggle to find these items if the exact words don’t match. This is where embeddings come in.
Embeddings let your system search by meaning rather than just matching words. By converting text into numerical vectors that represent semantic meaning, embeddings enable the identification of similar items even when they use different words.
Everyday use cases include:
- Semantic search (searching by meaning)
- Recommendation systems (finding similar products or documents)
- Duplicate detection (different phrasings, same idea)
- Chatbots and intent classification
How embeddings help
Think of embeddings as coordinates on a meaning map. Each phrase or word becomes a point in a high-dimensional space, where nearby points represent similar meanings.
Large language models learn to produce these vectors by analyzing huge training datasets; essentially, they observe how words and phrases are used in context across billions of examples.
If two words often appear in similar contexts or play similar semantic roles, their embeddings tend to be close in that space. For example, “Christmas” and “December festivity” frequently occur in similar kinds of sentences about holidays, family, gifts, and celebrations, so their numerical representations are close together.
Each embedding is a long array of numbers (a vector). When we compare two embeddings using a similarity or distance metric (such as cosine similarity), we can quantify how closely their meanings align. The closer the vectors, the more semantically related the terms are.
This is why embeddings can recognize that certain words or phrases can often be used interchangeably or belong to the same conceptual cluster, even if they don’t share exact words.
Why we’ll use single words (and when to prefer sentences)
In this article, we’ll simplify the concept by embedding single words.
It’s easier to see how similarity works between a few simple terms.
However, in real-world systems, you’ll usually embed sentences or short descriptions. Why?
- Context adds meaning: “Apple” could mean a fruit or a company; context resolves that.
- Sentence embeddings are more precise because they use word relationships and grammar.
- Phrases can invert meaning: “not good” vs. “good”. Individual words often miss that nuance.
When word vectors can fail vs. sentence vectors:
| Situation | Word-level Limitations | Sentence-level Strength |
|---|---|---|
| Ambiguous words (“bank”) | Can’t know which meaning | Sentence disambiguates |
| Negation (“not good”) | Misses combined meaning | Captures context |
| Intent (“how do I return my order?”) | Too sparse | Rich semantic info |
Tools used: PHP, Neuron AI, and Ollama
We’ll use PHP to demonstrate the concept because it’s easy to run and integrate with Neuron AI’s RAG tools.
Neuron AI provides convenient wrappers for embeddings, vector similarity, and RAG (Retrieval-Augmented Generation).
Ollama runs the embedding model locally, for example, nomic-embed-text.
Installation Steps
Ensure you have PHP 8 or later and Composer installed. Then run:
composer require neuron-core/neuron-ai
You’ll also need to have Ollama running locally:
ollama serve
ollama pull nomic-embed-text:latest
Introducing the example
We’ll compare the term “Christmas” with a list of related and unrelated words.
Reference word: Christmas
Words to compare:
- Christmas
- December festivity
- New Year
- Easter
- Car
- Bicycle
- Banana
Expectation: the similarity between “Christmas” and “December festivity” should be high, while unrelated words like “Banana” should be very low.
The PHP code
Here’s the complete example:
<?php
use NeuronAI\RAG\Embeddings\OllamaEmbeddingsProvider;
use NeuronAI\RAG\VectorSimilarity;
require "vendor/autoload.php";
// Create provider (configure API key and model)
$provider = new OllamaEmbeddingsProvider(
url: "http://localhost:11434/api",
model: "nomic-embed-text",
);
$referenceWord = "Christmas";
$wordList = [
"Christmas",
"December festivity",
"New Year",
"Easter",
"Car",
"Bicycle",
"Banana",
];
echo "Calculating embed" . PHP_EOL;
$referenceEmbedding = $provider->embedText($referenceWord);
$embeds = [];
foreach ($wordList as $word) {
echo "Calculating embed" . PHP_EOL;
$embeds[$word] = $provider->embedText($word);
}
echo "Vector similarity" . PHP_EOL;
foreach ($embeds as $word => $embedding) {
echo "sim($referenceWord, $word) = " .
VectorSimilarity::cosineSimilarity($referenceEmbedding, $embedding) .
PHP_EOL;
}
Step-by-step explanation
1. Import dependencies
require "vendor/autoload.php";
use NeuronAI\RAG\Embeddings\OllamaEmbeddingsProvider;
use NeuronAI\RAG\VectorSimilarity;
This loads Composer dependencies and brings in the classes for embeddings and similarity computation.
2. Create the provider
$provider = new OllamaEmbeddingsProvider(
url: "http://localhost:11434/api",
model: "nomic-embed-text",
);
This initialized the PHP Neuron AI provider to your local Ollama API using the nomic-embed-text model for generating embeddings.
If you want to use a different provider, for example, you want to use Gemini instead of Ollama, you can set up a different provider:
$provider = new GeminiEmbeddingsProvider(
key: "your-api-key",
model: "gemini-embedding-001", //
);
3. Set reference and word list
$referenceWord = "Christmas";
$wordList = [...];
Defines the base term to compare against and the list of words to analyze.
4. Generate embeddings
$referenceEmbedding = $provider->embedText($referenceWord);
foreach ($wordList as $word) {
$embeds[$word] = $provider->embedText($word);
}
Each word is transformed into a high-dimensional numeric vector that represents its meaning.
5. Compute similarities
foreach ($embeds as $word => $embedding) {
echo "sim($referenceWord, $word) = " .
VectorSimilarity::cosineSimilarity($referenceEmbedding, $embedding) .
PHP_EOL;
}
Uses cosine similarity (provided and implemented by Neuron AI) to measure how close each vector is to the reference.
Sample output
Your actual numbers will vary, but you can expect something like:
Calculating embed
Calculating embed
Calculating embed
Calculating embed
Calculating embed
Calculating embed
Calculating embed
Calculating embed
Vector similarity
sim(Christmas, Christmas) = 1
sim(Christmas, December festivity) = 0.80044420060232
sim(Christmas, New Year) = 0.62543668707038
sim(Christmas, Easter) = 0.64751234202926
sim(Christmas, Car) = 0.4313590955453
sim(Christmas, Bicycle) = 0.38693581208508
sim(Christmas, Banana) = 0.41243323374531
Values close to 1.0 mean strong similarity (same semantic concept). Lower values indicate weaker or no semantic relation.
Recap: when to use embeddings
Use embeddings when:
- You want to find related content, even if it uses different words.
- You’re building a recommendation system or semantic search.
- You need clustering or deduplication by meaning.
Avoid embeddings when:
- You only need exact keyword matching.
- The dataset is small and rule-based matching is easier.
Next steps
Try these enhancements:
- Replace single words with product descriptions or FAQ questions/answers.
- Store vectors in a vector database, such as Pinecone or Weaviate (Neuron AI provides you with several ready-to-use interfaces against several vector databases).
- Visualize embeddings using Python + PCA/UMAP to see the clusters.
- Experiment with different embedding models (https://ollama.com/search?c=embedding).
Final checklist
Before running:
- Start the Ollama server (
ollama serve). - Pull the model:
ollama pull nomic-embed-text. - Install Neuron AI with Composer.
- Run the script:
php embeddings-demo.php.
Once it runs, you’ll see numbers that measure meaning, your first taste of true semantic search.