无外部库实现K-means聚类时生成空簇列表问题求助
K-means手写实现簇样本分配问题修复
问题描述
当前正在实现面向大型数据集的K-means算法,全程不依赖第三方库自主编码,遇到的核心问题是无法根据簇中心坐标生成对应簇的归属样本列表。
测试数据集
dataset1 = [(6.08804, 3.457729), (4.147974, 5.275341), (6.538759, 3.670323), (4.579573, 4.03559), (4.756026, 4.184762), (5.221742, 2.872705)] cluster_1 = (0, 1) cluster_2 = (1, 2) clusters = [cluster_1, cluster_2] # 簇中心与数据集距离较远,仅用于逻辑测试
原有实现代码
1. 欧式距离计算函数
def calculate_distance(point1, point2): distance = 0 for i in range(len(point1)): # 欧氏距离公式 distance += (point1[i] - point2[i])**2 return distance**0.5
2. 最近簇中心匹配函数
def find_nearest_centre(dataset1, clusters): nearest_point = [] min_distance = 100000 for c in clusters: distance = calculate_distance(c, dataset) if distance < min_distance: min_distance = distance nearest_point.append(min_distance) return nearest_point
3. 簇样本列表生成函数
def create_list(dataset1, clusters): list_1 = [] list_2 = [] for d in dataset1: nearest_centre = find_nearest_centre(d, clusters) if nearest_centre == clusters[0]: list_1.append(d) elif nearest_centre == clusters[1]: list_2.append(d) return list_1, list_2
问题现象
调用create_list(dataset1, clusters)后返回的两个簇列表均为空,预期输出为前3个样本归属第一个簇,后3个样本归属第二个簇:
list_1 = [(6.08804, 3.457729), (4.147974, 5.275341), (6.538759, 3.670323)] list_2 = [(4.579573, 4.03559), (4.756026, 4.184762), (5.221742, 2.872705)]
问题定位与修复
原有代码存在3个核心逻辑错误:
- 参数引用错误:
find_nearest_centre函数内部调用calculate_distance时误用了未定义的dataset变量,参数命名dataset1易产生混淆(实际接收单个数据点) - 返回值不匹配:
find_nearest_centre当前返回的是最小距离列表,而非距离最近的簇中心元组,导致后续等于判断永远不成立,列表无法追加数据 - 匹配逻辑错误:仅记录最小距离数值,未同步记录距离最小的簇中心,输出不符合功能定位
修正后完整代码
# 欧式距离计算函数逻辑正确,无需修改 def calculate_distance(point1, point2): distance = 0 for i in range(len(point1)): distance += (point1[i] - point2[i])**2 return distance**0.5 # 修正最近簇中心匹配函数 def find_nearest_centre(point, clusters): min_distance = float('inf') nearest_cluster = None for c in clusters: distance = calculate_distance(c, point) if distance < min_distance: min_distance = distance nearest_cluster = c return nearest_cluster # 修正簇样本列表生成函数(核心逻辑无需修改,适配修改后的匹配函数即可) def create_list(dataset1, clusters): list_1 = [] list_2 = [] for d in dataset1: nearest_centre = find_nearest_centre(d, clusters) if nearest_centre == clusters[0]: list_1.append(d) elif nearest_centre == clusters[1]: list_2.append(d) return list_1, list_2
预期输出适配说明
当前测试用的簇中心(0,1)和(1,2)距离所有样本点的距离均是(1,2)更近,运行后所有样本会被分配到第二个簇。如果需要达到你给出的预期输出,可以调整簇中心为更贴合样本分布的取值,例如:
cluster_1 = (6, 3.5) cluster_2 = (4.5, 4)
运行后即可得到预期的分簇结果。
内容的提问来源于stack exchange,提问作者user14268322
相关产品推荐
相关产品推荐

