ML Foundations
Exclude row identity when checking nearest-neighbor predictions
A one-neighbor fixture scores perfectly by retrieving itself. Exclude the same row while retaining other samples with identical feature values.
Evidence and testing
Review record: Tensor Almanac automated evidence gate (no independent human review). Example versions, recorded outputs and limitations appear below.
Retrieving the query itself changes what a score measures
A one-neighbor classifier can recover each training label by retrieving the exact same row from its index. In the fixture, feature values (0, 1, 10, 11) have alternating labels (0, 1, 0, 1). Self-inclusive nearest-neighbor lookup returns row indices (0, 1, 2, 3), yielding accuracy 1.0. This checks label retrieval on indexed rows rather than prediction for unseen observations.
The scikit-learn kneighbors API distinguishes an explicit query array from omitting X. When X is omitted, it queries the indexed points while excluding each point from its own neighborhood. The example's supplemental estimator execution confirms the distinction for these four rows. [1]
References: [1]
Mask the diagonal only when both axes have the same row order
Run python examples/nearest_neighbor_self_match.py. It constructs a small square matrix of squared distances directly from the fixture values and assigns infinity to its diagonal before selecting each row's minimum. NumPy fill_diagonal modifies that diagonal in place. Here the same sample order appears on both axes, so diagonal entries represent the same indexed row. [2]
With self-matches excluded, the nearest indices become (1, 0, 3, 2). Every selected neighbor has the opposite label, so this fixture's accuracy becomes 0.0. Assertions verify both complete neighbor lists and both scores. A separate fitted scikit-learn one-neighbor classifier reproduced the explicit-query and omitted-query lists.
Diagonal masking is an identity shortcut for this square, identically ordered matrix. If queries are reordered, are a subset of the index, or come from a different collection, diagonal position no longer identifies a self-match. Carry sample identities and exclude matching identities according to the evaluation contract.
Executed with Python 3.12.14 and NumPy 2.3.5. Supplemental scikit-learn 1.8.0 KNeighborsClassifier execution is recorded in private review evidence. Exact stdout and source-byte SHA-256 are preserved.
"""Exclude row identity, not every zero-distance neighbor."""
import numpy as np
def squared_distances(values):
x = np.asarray(values, dtype=float)
if x.ndim != 1 or x.size < 2 or not np.isfinite(x).all():
raise ValueError("at least two finite one-feature samples required")
return (x[:, None] - x[None, :]) ** 2
def other_neighbor(values):
distances = squared_distances(values)
# Both axes have the same sample order, so the diagonal is row identity.
np.fill_diagonal(distances, np.inf)
return np.argmin(distances, axis=1)
def main():
x = np.array([0., 1., 10., 11.])
y = np.array([0, 1, 0, 1])
self_indices = np.argmin(squared_distances(x), axis=1)
other_indices = other_neighbor(x)
assert self_indices.tolist() == [0, 1, 2, 3]
assert other_indices.tolist() == [1, 0, 3, 2]
self_accuracy = float(np.mean(y[self_indices] == y))
excluded_accuracy = float(np.mean(y[other_indices] == y))
assert self_accuracy == 1.0 and excluded_accuracy == 0.0
duplicates = np.array([0., 0., 10.])
kept = other_neighbor(duplicates)
assert kept[:2].tolist() == [1, 0]
zero_masked = squared_distances(duplicates)
zero_masked[zero_masked == 0] = np.inf
wrong = np.argmin(zero_masked, axis=1)
assert wrong[:2].tolist() == [2, 2]
rejected = 0
for bad in ([], [1.], [0., float("nan")], [[0.], [1.]]):
try:
other_neighbor(bad)
except ValueError:
rejected += 1
assert rejected == 4
print("self-inclusive neighbor indices:", self_indices.tolist())
print("self-excluded neighbor indices:", other_indices.tolist())
print("same-row / self-excluded accuracy:", self_accuracy, excluded_accuracy)
print("duplicate rows retain each other:", kept[:2].tolist())
print("masking every zero wrongly selects:", wrong[:2].tolist())
print("invalid fixtures rejected:", rejected)
if __name__ == "__main__":
main()
Recorded output
self-inclusive neighbor indices: [0, 1, 2, 3] self-excluded neighbor indices: [1, 0, 3, 2] same-row / self-excluded accuracy: 1.0 0.0 duplicate rows retain each other: [1, 0] masking every zero wrongly selects: [2, 2] invalid fixtures rejected: 4
Zero distance does not uniquely identify the same row
The second fixture contains separate rows at feature values (0, 0, 10). The first two rows are valid zero-distance neighbors of one another after self-exclusion. Masking every zero distance incorrectly removes both relationships and sends each row to the distant third sample. The code asserts this contrast directly.
Whether duplicate records should share an evaluation group is a separate dataset decision. This example excludes only the same indexed row; it does not establish that retaining duplicates is appropriate for every validation objective. It uses one numeric feature and a dense quadratic-size distance matrix, suitable for the tiny fixture only. Four invalid inputs are rejected. Extreme-range arithmetic, learned preprocessing, hyperparameter selection and generalization estimation are outside the helper's scope. Other equal-distance choices also need a tie policy; scikit-learn warns that tied neighbor distances with different labels can make results depend on training order. [1]
References: [1]