Training a machine-learning model means adjusting numbers so that its predictions better match known answers. In this Excel workbook, you can see the entire process: the inputs, each prediction, the errors, and the calculations that determine the next adjustment.
The model is logistic regression, which estimates the probability of one of two outcomes. Here, it uses two measurements from breast mass samples to estimate whether each sample is malignant (cancerous) or benign (noncancerous). It has only three adjustable numbers, and you’ll train it by copying their proposed replacements into the cells that hold the current values. Excel handles the formulas; you control when an update happens.
You can follow along with basic Excel skills and no programming. We’ll make an update first, then trace how the workbook calculated it. This is an exercise in understanding training, using a small dataset with known diagnoses. It does not establish that the model can make reliable diagnoses on new samples.
Make your first update
Open the workbook and select the Parameters sheet. This is where you’ll work during training. The three yellow cells, B4:B6, hold the current parameters: the radius weight, the texture weight, and the bias. A weight multiplies an input measurement; the bias is a shared offset added to every sample’s score. We’ll examine both shortly.
The red cells, B22:B24, calculate proposed replacements for those parameters. They won’t become the current values until you paste them into the yellow cells. For now, watch accuracy, the share of samples labeled correctly, and loss, the error measure training tries to reduce. Both appear on Parameters. The Iteration Log already contains a separate 100-update reference run, and the first three charts show that saved run rather than automatically recording your changes.
- Set B4:B6 to zero and leave the learning rate in B9 at 0.1. The loss in B12 should be about 0.693, and accuracy in B13 should be 38.7%.
- Select and copy B22:B24 together. Select B4, then use Paste Special → Values to replace B4:B6. Paste all three cells at once so that the update uses one consistent model state. An ordinary formula paste would create circular references.
- Let Excel recalculate. The new parameters should be approximately 0.037584, 0.020843, and -0.011333, in that order. Loss should fall to 0.674 and accuracy should rise to 88.7%.
- Repeat the copy-and-paste operation four more times to complete five updates. Watch how loss changes even when accuracy stays the same. You don’t need to paste 100 times; the supplied log lets you inspect the longer run later.
If the numbers don’t change, make sure Excel’s calculation mode is set to Automatic. If Excel reports a circular reference, undo the paste and repeat it using Values. You can restart the exercise at any point by setting B4:B6 back to zero.
That first jump in accuracy is striking, but it doesn’t mean the model became highly confident after one update. Initially, every sample receives a probability of exactly 0.5, which the workbook counts as malignant. A small adjustment moves many benign samples below that cutoff and immediately changes their predicted labels. To understand how such a small change can produce a large jump, we need to follow the calculation from its inputs.
What the model is learning from
The workbook contains 150 samples from the Breast Cancer Wisconsin (Diagnostic) dataset. The measurements come from images of cells collected by fine needle aspiration of breast masses. They describe the cell nuclei visible in those images.
Each sample has two features, or input measurements, and a label, the known diagnosis:
| Workbook field | Meaning |
|---|---|
| Radius | Mean nuclear radius, based on distances from the nucleus center to its perimeter. |
| Texture | Mean nuclear texture, based on variation in grayscale values. Higher values indicate more variation in image brightness. |
| Malignant | The diagnosis encoded as 1 for malignant and 0 for benign. |
There are 58 malignant and 92 benign samples in this subset. The model learns from those labels, but its predictions use only radius and texture. This is binary classification, meaning that the task has two possible labels. Although “regression” is in the model’s name, its output here is a probability that we turn into a class prediction.
Standardize the measurements
Radius and texture have different numerical scales. Before using them, the workbook subtracts each feature’s mean and divides by its standard deviation:
\[x' = \frac{x - \mu}{\sigma}\]Here, \(x\) is the original measurement, \(\mu\) is the mean, and \(\sigma\) describes how spread out the measurements are. After this transformation, zero means the sample is at the mean; 1 means one standard deviation above it, and -1 means one standard deviation below it.
This is called standardization, or normalization in the workbook. It puts both inputs in comparable units, which helps keep their original measurement scales from dominating the sizes of the training adjustments. The model remains free to give one feature a larger weight if that improves its predictions.
On the Data sheet, columns B and C hold the raw measurements, D holds the labels, and E and F hold the standardized inputs. The means and standard deviations above the data are calculated from these same 150 samples.
From measurements to a prediction
For each sample, logistic regression multiplies the two standardized inputs by their weights and adds the bias:
\[z = w_1x_1 + w_2x_2 + b\]The radius input is \(x_1\), its weight is \(w_1\), and the texture pair is \(x_2\) and \(w_2\). The bias, \(b\), shifts the score for every sample. Because the inputs can be positive or negative, so can the resulting score, \(z\). We need another step before treating it as a probability.
The sigmoid function maps that score into a value between 0 and 1:
\[p = \frac{1}{1 + \exp(-z)}\]The expression \(\exp(-z)\) means \(e^{-z}\), where \(e\) is approximately 2.718. Negative scores give probabilities below 0.5, positive scores give probabilities above 0.5, and a score of zero gives exactly 0.5. The further the score moves from zero, the closer the output gets to one end of the range.
| Score z | Estimated probability of malignancy |
|---|---|
| -5 | 0.7% |
| 0 | 50% |
| 3.1 | 95.7% |
| 5 | 99.3% |
For a worked example, take a hypothetical malignant sample with standardized radius 1.5 and texture 0.8. Suppose the weights are 2 and 0.5, and the bias is -0.3. These are illustrative values, separate from the workbook’s reference run. They give:
\[z = 2(1.5) + 0.5(0.8) - 0.3 = 3.1\]Putting 3.1 through the sigmoid gives about 0.957, so this model assigns the sample a 95.7% probability of malignancy. The workbook converts probabilities into labels using a threshold: predict malignant when p is at least 0.5, otherwise predict benign. Our hypothetical sample is therefore classified correctly.
This rule also explains the workbook’s starting accuracy. With all three parameters at zero, every score is zero and every probability is 0.5. Every sample gets a malignant prediction, so only the 58 malignant samples count as correct: 58 out of 150 is 38.7%.
On the Training sheet, columns E, F, and K show the score, probability, and predicted label for each sample. Chart 6 on Visualizations shows the sigmoid’s shape if you want to see how scores map to probabilities.
Measuring how wrong a prediction is
Accuracy tells us whether a prediction falls on the correct side of 0.5. It doesn’t distinguish a probability of 0.51 from 0.99 when the sample is malignant; both count as correct. To train the model, we need a measure that responds to changes in probability even when the predicted label stays the same.
The workbook uses binary cross-entropy, also called log loss. It measures how little probability the model assigned to the known label. For a malignant sample, that probability is p. For a benign sample, it’s 1 - p. The loss is the negative natural logarithm of whichever probability corresponds to the correct label:
\[L_i = -\left[y_i\ln(p_i) + (1-y_i)\ln(1-p_i)\right]\]The subscript \(i\) identifies a sample, \(y_i\) is its label, and \(p_i\) is its predicted probability of malignancy. Since the label is either 0 or 1, one of the two terms disappears. The formula becomes \(-\ln(p_i)\) for a malignant sample and \(-\ln(1-p_i)\) for a benign one.
The logarithm makes confident mistakes expensive. Assigning the correct label a probability of 0.99 produces a loss of about 0.010; assigning it only 0.01 produces a loss of about 4.605. Our hypothetical malignant sample, with p about 0.957, has a small loss of about 0.044. If the same measurements belonged to a benign sample, that prediction would instead have a loss of about 3.144.
Training tries to reduce the average loss across all 150 samples. Column G contains the individual losses, and Parameters!B12 displays their average. The notation “Parameters!B12” means cell B12 on the Parameters sheet. At the zero-parameter starting point, every correct label receives probability 0.5, giving an average loss of about 0.693.
If you inspect column G’s Excel formula, you’ll see a different-looking expression built from the score, z. It calculates the same loss while avoiding the logarithm of zero, which can occur when Excel rounds an extreme probability to 0 or 1. The sigmoid formula in column F is also arranged to handle large positive and negative scores.
How the workbook chooses an adjustment
The three parameters affect every sample, so changing one can improve some predictions while worsening others. The workbook needs to account for all those effects. It does this by calculating the gradient: the slopes that describe how average loss changes as each parameter changes.
A positive slope means that a small increase in the parameter would increase the loss, so the update goes in the negative direction. A negative slope calls for an increase. Repeatedly moving in the opposite direction to the gradient is called gradient descent.
Start with each sample’s contribution
Differentiating the sigmoid and cross-entropy formulas gives a simple result: the slope of a sample’s loss with respect to its score is \(p-y\). This is a calculus result; you can use it here without deriving it. For a malignant sample, y is 1, so the slope is negative and increasing the score would lower the loss. For a benign sample, y is 0, so lowering the score would help instead.
A weight affects the score through its feature value. Increasing the radius weight raises the score for a sample with positive standardized radius, lowers it for one with negative standardized radius, and does nothing for one whose standardized radius is zero. That’s why the sample’s contribution to the weight gradient is \((p-y)x\).
For our hypothetical malignant sample, p - y is about -0.043. Multiplying by its standardized radius of 1.5 gives a radius-gradient contribution of about -0.065. This sample favors increasing the radius weight, although its contribution is small because the model already gives the correct label high probability. Other samples may favor a different change; the update uses their average.
We write the slope for a weight as \(\partial L/\partial w_j\), where \(j\) is 1 for radius or 2 for texture. The workbook averages the contributions from all samples:
\[\frac{\partial L}{\partial w_j} = \frac{1}{N}\sum_{i=1}^{N}(p_i-y_i)x_{j,i}\]Here, \(N=150\), and the summation symbol means to add the contributions from all samples before dividing by N. The bias enters every score directly, so its gradient is just the average of p - y:
\[\frac{\partial L}{\partial b} = \frac{1}{N}\sum_{i=1}^{N}(p_i-y_i)\]On Training, column H contains p - y, while I and J multiply it by standardized radius and texture. Their averages appear in Parameters!B17:B19 as the three gradients. These are calculated from the current parameters, not from the saved reference log.
Take a step in the improving direction
The update follows the same rule for each parameter:
\[\text{new value} = \text{current value} - \alpha\times\text{gradient}\]The learning rate, \(\alpha\), controls the step size. At the workbook’s default of 0.1, the initial radius gradient of about -0.37584 gives a new weight of 0 - 0.1 × (-0.37584), or about 0.037584. The texture gradient is about -0.20843, and the bias gradient is about 0.11333, producing the other two values you pasted during the first update.
The gradient describes what happens with a small change. The learning rate sets the size of the actual step, and a step that is too large can overshoot and increase loss. A smaller rate generally makes more gradual changes. This is why comparing learning rates requires the same starting parameters and the same number of updates.
The red cells calculate all three replacements from the current model. Pasting them into the yellow cells applies the update, after which Excel recalculates the predictions, loss, and gradients. Since each update uses all 150 samples, one update here is also one full pass through the dataset, or epoch. In methods that update on smaller batches, an epoch contains several updates.
Follow the longer training run
The Iteration Log records the workbook’s reference run from iteration 0, before any updates, through iteration 100. These are saved values, so your manual updates won’t change them. Charts 1–3 use this log to show loss, accuracy, and parameter values over time.
| Completed updates | Average loss | Training accuracy |
|---|---|---|
| 0 | 0.693 | 38.7% |
| 1 | 0.674 | 88.7% |
| 10 | 0.545 | 88.7% |
| 20 | 0.463 | 88.7% |
| 50 | 0.354 | 88.7% |
| 80 | 0.309 | 90.0% |
| 100 | 0.291 | 90.0% |
After the first update moves many samples across the threshold, accuracy stays at 88.7% for much of this run. Loss continues to fall because the probabilities are changing even while the number of correct labels stays the same. A malignant sample moving from p = 0.6 to p = 0.8 remains correctly classified, but its loss decreases.
The overall loss combines changes across every sample. It can decrease even if accuracy occasionally falls, because an improvement in many probabilities can outweigh a few threshold crossings in the wrong direction. By iteration 100, the loss is decreasing more slowly, but 100 is simply the length of the supplied run; it isn’t proof that training has finished.
Inspect the model at iteration 100
To make the live charts match the end of the reference run, copy Iteration Log!D106:F106. Select Parameters!B4 and use Paste Special → Values with Transpose selected. Transpose turns the horizontal row into the vertical B4:B6 cells. This loads the saved state; it does not apply another update.
The weights should now be about 1.628 for radius and 0.590 for texture, with a bias of -0.452. Because both inputs are standardized, you can compare the effects of a one-standard-deviation increase: radius raises the score by about 1.628, while texture raises it by about 0.590, holding the other feature fixed. These coefficients describe how this model uses its inputs, not their clinical importance.
For a sample at the mean of both features, the standardized inputs are zero and the bias alone sets the score. A score of -0.452 gives a probability of about 0.389. The model fits the bias alongside the weights; it isn’t simply a copy of the malignant proportion in the dataset.
Look at the mistakes
On Visualizations, Chart 5 plots current probabilities separately for malignant and benign samples. A malignant sample below 0.5 is missed; a benign sample at or above 0.5 is incorrectly labeled malignant. After loading iteration 100, the errors break down as follows:
| Known diagnosis | Predicted malignant | Predicted benign |
|---|---|---|
| Malignant, 58 samples | 46 | 12 |
| Benign, 92 samples | 3 | 89 |
The 135 correct predictions give 90% accuracy, but this table shows something the single percentage hides: the model misses 12 of the 58 malignant samples. Chart 7 also updates with the current parameters, showing all probabilities in the original sample order. Use Chart 5 when you want to distinguish the two known classes.
The classification table at the bottom of Parameters shows these counts for the current model. As you change the parameters, you can watch which kind of error becomes more or less common.
Some errors are easier to understand by looking at the inputs. Chart 4 plots raw radius against raw texture, with the samples grouped by known diagnosis. The groups overlap. Logistic regression assigns its classes using a straight decision boundary, where the score is zero and the probability is 0.5:
\[w_1x_1 + w_2x_2 + b = 0\]That line is expressed here in standardized coordinates; standardization also preserves its straight shape in the raw coordinates used by Chart 4. The chart shows the samples, not a fitted boundary line. Changing the parameters shifts or rotates the boundary, but a single straight line has limited flexibility when the classes overlap.
Keep a log of your own run
If you want to record your manual updates, save a separate copy of the workbook first. In that copy, clear the contents of Iteration Log!A6:F106, keeping the headings and formatting. This removes the saved reference values so that your early updates won’t be plotted alongside later rows from a different run.
Reset Parameters!B4:B6 to zero and record that starting state in row 6 of Iteration Log:
- Enter 0 in column A for the iteration number.
- Copy Parameters!B12:B13 into B6:C6, using Paste Special → Values with Transpose selected. This records current loss and accuracy.
- Copy Parameters!B4:B6 into D6:F6 with the same paste options. This records the parameters that produced those results.
After one update, record iteration 1 in row 7, then continue downward. Always record the current yellow-cell parameters with the current metrics. The red cells contain the next proposed parameters; using them in the log would pair one model’s results with another model’s weights.
Charts 1–3 will now follow your recorded values. Their existing ranges cover rows 6–106, enough for the starting state and 100 updates. Keep this exercise within those rows so that every recorded update appears in the charts.
What this exercise tells you, and what remains untested
The model’s 90% accuracy describes its fit to the same 150 samples used to choose the parameters. It gives no direct measurement of performance on new samples. Even a small model can learn patterns that don’t carry over, a problem called overfitting.
To evaluate new-sample performance, we would set aside test data before training and keep it out of decisions about the model. If we wanted to choose settings by comparing performance on unseen examples, we would use separate validation data for that choice and reserve the test set for the final evaluation. Both would be standardized using the training set’s means and standard deviations.
The probabilities need checking too. Calibration asks whether predicted probabilities match observed frequencies: among enough comparable samples assigned a probability near 0.8, about 80% should be malignant. Mapping a score through the sigmoid creates a probability estimate, but does not establish that this estimate is calibrated. Neither calibration nor performance on new samples is measured by the workbook’s training accuracy.
You can still learn a great deal from this small model. Before closing the workbook, try two five-update runs from zero, one with learning rate 0.1 and one with 0.01. Compare their final losses, then inspect a sample’s probability and gradient contribution in Training. The calculations now give you a way to explain why the runs differ, even if their accuracy is identical.
Further reading
- The UCI dataset documentation describes the original measurements and their source.
- Stanford’s logistic regression notes develop the probability model, loss, and derivatives in more mathematical detail.