XOR Boundary
An XOR label over two features: no linear boundary beats 0.75 accuracy. Reach 0.90 on held-out rows with an engineered interaction.
Higher is better. Scored on 20 held-out rows.
Dataset
- class 0
- class 1
Each dot is one training row: feature 1 against feature 2, coloured by class.
What this lab teaches
XOR is the canonical proof that linear models need a feature: the product x1*x2 turns a non-separable label into a separable one.
The four-quadrant pattern
The 32 training rows arrive in mirrored quadruples at (+-x1, +-x2), with label 1 when the signs agree and label 0 when they differ - 16 ones and 16 zeros. The 20 hidden rows follow the same construction. Because the two positive regions sit on opposite diagonals, no straight boundary can isolate both without also catching a negative region.
Why 0.75 is the linear ceiling
Any line through the plane slices it into two half-planes; at best it captures three of the four quadrants, so a linear model tops out near 0.75 accuracy, which is the recorded baseline. The starter's constant majority vote (rate 0.5 is not greater than 0.5, so it predicts 0) scores 10/20 = 0.50 on the hidden rows.
The product feature
z = x1*x2 is positive exactly in the two label-1 quadrants and negative in the two label-0 quadrants, so the rule z > 0 scores 1.00 on the hidden rows. Logistic regression on [x1, x2, x1*x2] discovers the same boundary; standardize the rows after building the three columns so the product is on a comparable scale.
Common pitfalls
- Adding x1-squared and x2-squared but not the interaction. Squares are identical across mirrored quadrants, so XOR stays invisible to the model.
- Standardizing the raw features and then multiplying the standardized values without refitting the scale of the product column. The engineered feature's magnitude decides how much it can move the boundary.
- Stopping at 0.75 because it beats chance. That is exactly the linear ceiling and the baseline; the target is 0.90 and only the interaction gets there.
Rules of the run
- Define predict(train_X, train_y, test_X) and return exactly one value per test row.
- Pure Python or numpy both run; no external data or network access.
- Return probabilities or 0/1 labels; values are thresholded at 0.5.
- The two raw features alone cannot reach the target.
Hint
Add x1 times x2 as a third feature (x1-squared and x2-squared can help too), standardize, and fit logistic regression.
Reference solution
Revealing doesn't affect your record — but try the hint first.