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

如何在自定义ODKM类中优雅获取KMeans聚类的各项计算指标和结果

ODKM聚类信息导出实现方案

改造思路

  • 在类初始化阶段新增多个实例属性,存储拟合、预测过程产生的所有核心聚类数据
  • 改造fit方法,将聚类标签、中心、距离矩阵、effect值计算结果同步存储
  • 改造predict方法,缓存最近一次预测的样本标签和得分结果
  • 新增KM_summary方法,支持两种格式的信息输出:全量配置字典、可直接拼接进原数据集的样本级结果表
import math
from math import pow
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans


class ODKM:
    
    def __init__(self,n_clusters=15,effectiveness=500,max_iter=2, random_state=42):
        self.n_clusters=n_clusters
        self.effectiveness=effectiveness
        self.max_iter=max_iter
        self.random_state = random_state # 新增固定随机种子,保证结果可复现
        # 原有存储属性
        self.kmeans = {}
        self.cluster_score = {}
        # 新增聚类信息存储属性
        self.column_labels = {} # 存储训练集每列的聚类标签
        self.column_centers = {} # 存储每列的聚类中心
        self.column_dist = {} # 存储每列的聚类中心距离矩阵
        self.column_effect = {} # 存储每列的effect计算矩阵
        self.last_predict_labels = {} # 存储最近一次预测的样本聚类标签
        self.last_score_array = None # 存储最近一次预测的ODKM得分
        
    def fit(self, data):
        length = len(data)
        for column in data.columns:
            kmeans = KMeans(
                n_clusters=self.n_clusters,
                max_iter=self.max_iter,
                random_state=self.random_state
            )
            self.kmeans[column]=kmeans
            kmeans.fit(data[column].values.reshape(-1,1))
            # 存储聚类标签、中心
            self.column_labels[column] = kmeans.labels_
            self.column_centers[column] = kmeans.cluster_centers_.flatten()
            # 初始化当前列的距离、effect矩阵
            self.column_dist[column] = np.zeros((self.n_clusters, self.n_clusters))
            self.column_effect[column] = np.zeros((self.n_clusters, self.n_clusters))
            
            assign = pd.DataFrame(kmeans.predict(data[column].values.reshape(-1,1)),columns=['cluster'])
            cluster_score=assign.groupby('cluster').apply(len).apply(lambda x:x/length)
            ratio=cluster_score.copy()
        
            sorted_centers = sorted(kmeans.cluster_centers_)
            max_distance = ( sorted_centers[-1] - sorted_centers[0] )[ 0 ]
        
            for i in range(self.n_clusters):
                for k in range(self.n_clusters):
                    if i != k:
                        dist = np.abs(kmeans.cluster_centers_[i] - kmeans.cluster_centers_[k])/max_distance
                        effect = ratio[k]*(1/pow(self.effectiveness,dist))
                        cluster_score[i] = cluster_score[i]+effect
                        # 存储当前dist、effect值
                        self.column_dist[column][i][k] = dist
                        self.column_effect[column][i][k] = effect
                        
            self.cluster_score[column] = cluster_score
                    
    def predict(self, data):
        length = len(data)
        score_array = np.zeros(length)
        # 清空上一次预测的标签缓存
        self.last_predict_labels = {}
        for column in data.columns:
            kmeans = self.kmeans[ column ]
            cluster_score = self.cluster_score[ column ]
            
            assign = kmeans.predict( data[ column ].values.reshape(-1,1) )
            # 存储当前列的预测标签
            self.last_predict_labels[f'{column}_cluster_label'] = assign
            
            for i in range(length):
                score_array[i] = score_array[i] + math.log10( cluster_score[assign[i]] )
        # 存储当前预测得分
        self.last_score_array = score_array
        return score_array
    
    def fit_predict(self,data):
        self.fit(data)
        return self.predict(data)
    
    def KM_summary(self, return_type='dict'):
        """
        导出聚类全量信息
        :param return_type: 可选值
            'dict':返回全量聚类配置的嵌套字典
            'predict_df':返回最近一次预测的样本级标签+得分DataFrame,可直接拼接原数据集
        """
        if return_type == 'dict':
            return {
                'cluster_centers': self.column_centers,
                'train_sample_labels': self.column_labels,
                'cluster_distance_matrix': self.column_dist,
                'cluster_effect_matrix': self.column_effect,
                'cluster_score': self.cluster_score
            }
        elif return_type == 'predict_df':
            predict_res = pd.DataFrame(self.last_predict_labels)
            predict_res['ODKM_Score'] = self.last_score_array
            return predict_res

使用示例

import pandas as pd

df = pd.DataFrame(data={'attr1':[1,1,1,1,2,2,2,2,2,2,2,2,3,5,5,6,6,7,7,7,7,7,7,7,15],
                         'attr2':[1,1,1,1,2,2,2,2,2,2,2,2,3,5,5,6,6,7,7,7,13,13,13,14,15]})


odkm_model = ODKM(n_clusters=3, max_iter=1)
result = odkm_model.fit_predict(df)

# 直接将聚类标签、得分合并到原DataFrame
df = pd.concat([df, odkm_model.KM_summary(return_type='predict_df')], axis=1)

# 单独获取全量聚类信息做可视化
cluster_info = odkm_model.KM_summary(return_type='dict')
# 示例:获取attr1的聚类中心
attr1_centers = cluster_info['cluster_centers']['attr1']

扩展说明

如果需要单独获取某列的KMeans原生对象,直接调用odkm_model.kmeans['attr1']即可,原生的cluster_centers_、labels_等属性都可以正常访问,和无封装的使用习惯完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:15:02