使用sklearn.utils.shuffle为K近邻分类器数据集添加噪声后模型精度无变化的问题排查
问题分析与解决方案
你的问题出在你并没有真正给训练数据添加“噪声”——当前的操作只是把正确的训练样本重复了一遍,模型看到的依然是标签和特征完全匹配的样本,自然精度不会下降。
为什么原代码无效?
sklearn.utils.shuffle(X_train, y_train, n_samples=50)的作用是打乱训练样本的顺序,但每个样本的特征X_shuffled和标签y_shuffled依然是正确配对的。你把这些样本和原训练集拼接后,只是扩充了训练集的大小(增加了50个正确样本),没有引入任何错误或干扰信息,模型的性能当然不会变化(甚至可能因为数据量变大略有提升)。
用resample的情况也是同理:默认的重采样是有放回地抽取正确样本,同样不会引入噪声。
正确的噪声添加方法
要监控模型在噪声数据下的性能,你需要引入破坏特征与标签对应关系或者污染特征本身的样本,以下是几种常用的实现方式:
1. 打乱标签制造错误配对样本
这种方式是让部分样本的特征和标签完全不匹配,模拟标签噪声:
import numpy as np from sklearn.utils import shuffle from sklearn.neighbors import KNeighborsClassifier # 抽取50个训练样本(特征和标签原本是正确配对的) X_shuffled, y_shuffled = shuffle(X_train, y_train, random_state=0, n_samples=50) # 打乱这50个样本的标签,让特征和标签不再匹配 y_noisy = shuffle(y_shuffled, random_state=1) # 拼接原数据和噪声数据 X_noisy = np.concatenate((X_train, X_shuffled)) y_final = np.concatenate((y_train, y_noisy)) knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_noisy, y_final) print('accuracy: ', knn.score(X_test, y_test))
2. 给特征添加随机噪声
这种方式是在特征上加入干扰,模拟数据采集时的噪声:
import numpy as np from sklearn.neighbors import KNeighborsClassifier # 抽取50个训练样本 X_noisy_features = X_train[:50].copy() # 添加高斯噪声(均值0,标准差可根据你的数据分布调整,比如0.1) X_noisy_features += np.random.normal(loc=0, scale=0.1, size=X_noisy_features.shape) # 拼接原数据和特征带噪声的样本(标签依然正确) X_noisy = np.concatenate((X_train, X_noisy_features)) y_final = np.concatenate((y_train, y_train[:50])) knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_noisy, y_final) print('accuracy: ', knn.score(X_test, y_test))
3. 随机替换部分标签为错误值
直接修改部分样本的标签为其他类别,模拟标签标注错误:
import numpy as np from sklearn.neighbors import KNeighborsClassifier # 复制原训练标签 y_noisy = y_train.copy() # 随机选择50个样本,把它们的标签替换为随机的其他类别 noise_indices = np.random.choice(len(y_train), size=50, replace=False) # 获取所有可能的类别 unique_classes = np.unique(y_train) for idx in noise_indices: # 随机选一个不等于原标签的类别 wrong_label = np.random.choice([c for c in unique_classes if c != y_noisy[idx]]) y_noisy[idx] = wrong_label knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train, y_noisy) print('accuracy: ', knn.score(X_test, y_test))
尝试这些方法后,你应该能看到模型精度出现预期的下降,从而可以监控模型在噪声环境下的鲁棒性。
内容的提问来源于stack exchange,提问作者Me0002
相关产品推荐
相关产品推荐

