import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 1. 构造带有特定分布的模拟数据集
np.random.seed(42)
N = 200
X = np.random.normal(loc=10.0, scale=5.0, size=(N, 4))
y = (X[:, 0] + X[:, 1] > 20.0).astype(int)
# 强制注入几条数值极大的远端离群样本 (模拟测试集潜在突变)
X_dirty = X.copy()
X_dirty[-20:, :] += 50.0
# ================= 错误路径:全量 fit 导致数据泄漏 =================
scaler_wrong = StandardScaler()
X_scaled_wrong = scaler_wrong.fit_transform(X_dirty) # 违规全量 fit!
X_tr_w, X_te_w, y_tr_w, y_te_w = train_test_split(X_scaled_wrong, y, test_size=0.2, random_state=42)
model_wrong = KNeighborsClassifier(n_neighbors=3)
model_wrong.fit(X_tr_w, y_tr_w)
acc_wrong = accuracy_score(y_te_w, model_wrong.predict(X_te_w))
# ================= 正确路径:严格隔离,仅在 Train 上 fit =================
X_tr_raw, X_te_raw, y_tr, y_te = train_test_split(X_dirty, y, test_size=0.2, random_state=42)
scaler_correct = StandardScaler()
X_tr_correct = scaler_correct.fit_transform(X_tr_raw) # 仅在 Train fit!
X_te_correct = scaler_correct.transform(X_te_raw) # 对 Test 仅 transform!
model_correct = KNeighborsClassifier(n_neighbors=3)
model_correct.fit(X_tr_correct, y_tr)
acc_correct = accuracy_score(y_te, model_correct.predict(X_te_correct))
print(f"错误全量 fit 下的测试集准确率: {acc_wrong * 100:.2f}% (虚假虚高表现)")
print(f"严格隔离 fit 下的测试集准确率: {acc_correct * 100:.2f}% (真实的泛化性能)")