Foundations: Python, Git and toolsLoading progress…

Plotting and notebooks

Use array shapes, broadcasting and reductions to express a small data transformation.

A plot is a claim about two quantities

A plot turns arrays into shapes you can see, but the shape means nothing until you say what each axis measures and in what unit. The recipe is always the same: compute the x values and the y values as arrays of equal length, then draw one against the other. The usual Python library for this is matplotlib. It is large, so here we only compute the arrays in NumPy and draw them with a small plot component of our own. The thinking is identical.

plt.plot(w, loss)
plt.xlabel("candidate weight w")
plt.ylabel("mean squared error (loss)")
0123404.679.331418.67

The same 41 points. A curve with a dip, but you cannot say what is on either axis, so you cannot use it.

The same 41 points, with and without labels. Tick the box.

Notebooks: the screen shows an order, the kernel remembers another

A notebook is a list of cells that you can run in any order, any number of times. The program state lives in a separate kernel (a running Python process), not in the page. Each cell shows a counter like In [3]: the order in which cells actually ran. Editing a cell changes the page, not the kernel, until you run it.

That gap produces hidden state bugs. Step through a small one:

step 1 of 6

A fresh kernel. Nothing has run, so the kernel has no variables.

In [ ]scores = np.array([0.2, 0.5, 0.7, 0.9, 0.4]) # cell 1
In [ ]threshold = 0.6 # cell 2
In [ ]flagged = scores > threshold # cell 3
In [ ]print(flagged.sum()) # cell 4
kernel memory: (empty)

A clean run would print 2. Some cells have not run yet.

Four cells: load scores, set a threshold, flag scores above it, count them. The banner compares the screen with what a clean run would print.

Predict first. You change threshold = 0.6 to 0.8 in cell 2 but only re-run cell 4 (the count). What does it print?

The common mistake and the habit that prevents it

A notebook that works only because of what you ran earlier cannot be reproduced by anyone else, including you tomorrow. Before you trust a result or share a notebook, use restart the kernel and run all cells in order. If it fails or changes the answer, the notebook had hidden state.

Chapter context

A tensor is a multidimensional array with a shape and element type. Many AI bugs come from doing a valid operation along the wrong axis. Write the intended dimensions before trying to shorten the code.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

For a data matrix X∈Rn×dX\in\mathbb R^{n\times d}, feature means are

μj=1n∑i=1nXij,Zij=Xij−μj.\mu_j=\frac1n\sum_{i=1}^n X_{ij},\qquad Z_{ij}=X_{ij}-\mu_j.

Here i indexes examples and j indexes features. The mean vector has d entries, so subtracting it from X broadcasts along rows.

Worked example

For X = [[1, 2], [3, 4]], the feature means are [2, 3]. Centering produces [[-1, -1], [1, 1]]. Each centered column has mean zero. Computing row means instead would answer a different question even though the operation is valid.

Reference code

The following example uses the Python standard library and does not call a remote service.

X = [[1, 2], [3, 4]]
means = [sum(row[j] for row in X) / len(X) for j in range(2)]
centered = [[x - m for x, m in zip(row, means)] for row in X]
assert means == [2, 3]
assert centered == [[-1, -1], [1, 1]]

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Broadcasting is a shape rule, not permission to ignore axis meanings. Vectorized code can create large intermediate arrays. Normalize training and test data with training statistics only.