nearestcentroid适用于类别分布近似球形、边界近似线性、特征已标准化、类别数少而样本量大的场景;不支持缺失值和样本权重,质心为算术均值,曼哈顿距离下仍用欧氏均值导致几何直觉偏差。

NearestCentroid 适合什么场景
NearestCentroid 不是黑盒模型,它只计算每个类别的样本均值作为“质心”,预测时把新样本分给欧氏距离最近的质心。这意味着它快、可解释、内存占用低,但对类别内分布不均衡或非凸形状的数据很敏感。
- 类别间边界近似线性且大致球形分布时效果稳定
- 特征已标准化(尤其量纲差异大时),否则距离会被大尺度特征主导
- 样本量大但类别数少(比如 10 个类别、10 万样本),训练几乎无开销
- 不能处理缺失值:
fit()会直接报ValueError: Input contains NaN
为什么 predict() 结果和直觉不符
常见错因不是算法本身,而是预处理不一致或质心定义被误读:
-
NearestCentroid默认用 未加权的算术平均 计算质心,不支持类别权重(sample_weight被忽略) - 如果某类样本极少(如只有 2 个点),它的质心可能严重偏离真实中心,导致预测偏移
- 使用
metric='manhattan'时,质心仍是按欧氏意义计算的均值,只是距离度量换成了曼哈顿距离——这会导致“最近”结果与几何直觉冲突
示例:
from sklearn.neighbors import NearestCentroid import numpy as np X = np.array([[0, 0], [0, 1], [1, 0], [10, 10]]) # 前三样本属 class 0,最后属 class 1 y = np.array([0, 0, 0, 1]) clf = NearestCentroid() clf.fit(X, y) print(clf.centroids_) # [[0.33, 0.33], [10., 10.]] —— class 0 质心被拉向原点附近 print(clf.predict([[0.5, 0.5]])) # 输出 [0],合理;但 [[9, 9]] 也会被判为 [0](因 8.67 <h3>如何避免质心被异常值拖偏</h3><p><code>NearestCentroid</code> 本身不提供鲁棒质心选项,但可通过预处理缓解:</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5772" title="Python Use Agent"><img src="https://img.php.cn/upload/skill/000/000/081/179065807481489.jpg" alt="Python Use Agent" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill5772" title="Python Use Agent" class="overflowclass">Python Use Agent</a> <p class="overflowclass">智能执行Python任务,自动生成、执行代码并反馈结果,无需额外配置,兼容旧命令。</p> </div> <a rel="nofollow" href="/xiazai/skill5772" title="Python Use Agent" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>
- 用
shrink_threshold启用收缩版质心(即“shrunken centroid”):对每个特征维度独立做阈值截断,抑制噪声维度影响 - 先对每类做离群点过滤(如用
LocalOutlierFactor或 IQR),再拟合NearestCentroid - 改用
sklearn.cluster.KMeans配合硬分配(虽非分类器,但可手动构建类中心)
关键参数行为:
-
shrink_threshold=0.1表示将每维质心值压缩:若原始均值绝对值 -
shrink_threshold=None(默认)即不收缩,完全依赖原始均值
与 KNeighborsClassifier 的关键区别在哪
两者都靠距离判别,但机制完全不同:
-
NearestCentroid是一次性建模:训练即算完质心,predict 是 O(k×n_features) 操作(k 为类别数) -
KNeighborsClassifier(n_neighbors=1)是懒学习:训练不计算,predict 时才遍历全部训练样本,复杂度 O(n_samples×n_features) - 当训练集达百万级、类别仅十几个时,
NearestCentroid的内存和速度优势明显;但若类别边界高度不规则,它连KNeighborsClassifier(n_neighbors=3)的基础平滑能力都没有 -
NearestCentroid不支持概率输出(predict_proba报AttributeError),也没decision_function
真正容易被忽略的是:它不校准距离尺度。如果你后续要用该距离做阈值过滤(如只接受距离 centroids_ 和输入做归一化,否则数值无业务意义。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










