You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带字符串索引数据集的K-Means聚类离群点识别Python代码实现问询

K-Means聚类离群点识别的Python实现

背景

  • 有一个索引为字符串(如'1234a'、'abcd'等非整数类型)的input_df
  • 已完成k=100的K-Means聚类,得到两个结果:
    • centroids:100个聚类中心,对应每个簇的样本均值
    • labels:与input_df行数一致,标记每个样本所属的聚类簇

离群点识别逻辑

先明确伪代码的核心逻辑,尤其是你疑惑的第4行:

c_x : 样本点x对应的聚类中心,其中x ∈ X

1. 计算每个点到其对应聚类中心的L2距离(欧几里得距离)。
2. t = L2距离的95%分位数(即95%的样本距离都小于等于t,剩余5%的大距离样本就是离群点)。
3. 遍历每个样本点x:
4.     若样本x到其对应聚类中心c_x的欧几里得距离 > t,则
5.          将x标记为离群点

注:|| x - c_x ||₂就是L2范数,等价于两点间的欧几里得距离,条件的意思是:当样本到自身簇中心的距离超过95%的样本距离时,判定为离群点。

符合要求的Python实现

以下是完全匹配你给出的代码结构的实现:

import numpy as np
from sklearn.cluster import KMeans

def remove_outliers(input_df, centroids, labels):
    # 将DataFrame转为numpy数组,方便向量运算
    X = input_df.values
    # 为每个样本匹配对应的聚类中心
    matched_centroids = centroids[labels]
    # 计算每个样本到对应簇中心的L2距离(欧几里得距离)
    l2_distances = np.linalg.norm(X - matched_centroids, axis=1)
    # 计算95%分位数t——95%的样本距离都不超过这个值
    threshold = np.percentile(l2_distances, 95)
    # 生成非离群点的掩码
    keep_mask = l2_distances <= threshold
    # 过滤labels:只保留非离群点的标签
    filtered_labels = labels[keep_mask]
    # 过滤centroids:只保留还有非离群点的簇的中心
    remaining_clusters = np.unique(filtered_labels)
    filtered_centroids = centroids[remaining_clusters]
    
    return filtered_centroids, filtered_labels

# 示例调用流程
kmeans = KMeans(n_clusters=100, random_state=42)
kmeans.fit(input_df)
centroids = kmeans.cluster_centers_
labels = kmeans.labels_

filtered_centroids, filtered_labels = remove_outliers(input_df, centroids, labels)

关键代码说明

  • np.linalg.norm(X - matched_centroids, axis=1):按行计算每个样本与对应簇中心的L2距离,axis=1确保对每个样本单独计算距离
  • np.percentile(l2_distances, 95):直接计算距离的95%分位数,作为离群点判定的阈值
  • 过滤聚类中心时,会移除所有样本都被判定为离群点的簇(如果有的话)

内容的提问来源于stack exchange,提问作者Ash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 06:30:00