Chapter 2 · Vectors and Matrices
Vectors: Data as Lists of Numbers
- Page 2 of 17
- 3 min read
A vector is an ordered list of numbers. That is all — but it is how AI sees everything. A house becomes [size, bedrooms, distance]. A pixel is [red, green, blue]. A sentence, after an embedding model reads it, becomes a list of 1,536 numbers. Once data is a vector, you can measure it, compare it and compute with it.
You can picture a vector with two numbers as an arrow on a grid: [3, 4] means "3 to the right, 4 up". With 1,536 numbers you cannot picture it, but every rule below still works exactly the same way.
Adding and scaling
import numpy as np
a = np.array([3, 4])
b = np.array([1, 2])
print(a + b) # add element by element
print(a - b)
print(2 * a) # scale: every element times 2
print(np.linalg.norm(a)) # length: the square root of 3² + 4²[4 6]
[2 2]
[6 8]
5.0- Adding two vectors adds matching elements. As arrows: walk along one, then the other.
- Scaling multiplies every element by the same number: same direction, longer or shorter.
- The length or norm, written
‖a‖, is Pythagoras in any number of dimensions: the square root of the sum of the squares. For[3, 4]that is √(9 + 16) = 5.
Distance: how different are two things?
The distance between two vectors is the length of their difference. Small distance, similar things:
import numpy as np
# Three flats: [size in 100 m², bedrooms, distance to centre in km]
flat_a = np.array([0.9, 2, 3.0])
flat_b = np.array([1.0, 2, 3.5])
flat_c = np.array([2.4, 4, 12.0])
print(round(np.linalg.norm(flat_a - flat_b), 2)) # a and b are close
print(round(np.linalg.norm(flat_a - flat_c), 2)) # a and c are far apart
unit = flat_c / np.linalg.norm(flat_c) # same direction, length 1
print(unit.round(3), round(np.linalg.norm(unit), 3))0.51
9.34
[0.186 0.311 0.932] 1.0Dividing a vector by its own length gives a unit vector: same direction, length exactly 1. This is called normalising, and embedding search uses it all the time (next page).
Watch the scales. In the flats above, the distance in kilometres (3.0 vs 12.0) dominates the distance, while a difference in size hardly counts. Features measured in different units must be put on a common scale first — page 10 shows how.
Embeddings: meaning as a direction
An embedding is a vector that a model produces so that things with similar meaning end up close together. Real embeddings have hundreds of numbers learned from huge amounts of text. Here is a toy version with three hand-made numbers, to show the famous idea that relationships become directions:
import numpy as np
# Toy 3-number "embeddings": [royalty, maleness, is-a-person]
words = {
"king": np.array([0.95, 0.90, 1.0]),
"queen": np.array([0.95, 0.05, 1.0]),
"man": np.array([0.05, 0.92, 1.0]),
"woman": np.array([0.05, 0.04, 1.0]),
"apple": np.array([0.00, 0.00, 0.0]),
}
target = words["king"] - words["man"] + words["woman"]
print(target.round(2))
closest = min(words, key=lambda w: np.linalg.norm(words[w] - target))
print(closest)[0.95 0.02 1. ]
queenking − man + woman lands closest to queen: subtracting man removes "maleness", adding woman puts the other value back, and royalty stays. Real embedding models learn directions like this on their own — that is what makes semantic search, recommendations and RAG possible.
Try it yourself
- Compute the length of
[1, 2, 2]by hand, then check with NumPy. - Add a fourth flat to the distance example and find which existing flat it is closest to.
- In the analogy, compute
queen − woman + man. Which word is closest?