python 聚类_k-means聚类算法,简短易懂的python代码

k-means算法原理上可以说蛮简单的,面试上也会经常问到,但一旦面试官问到如何用python写出来,有些同学可能一时半会还不知道咋下手,导致写的磕磕绊绊,影响面试体验。今个我们就来彻底学懂它!

先介绍原理:

先给定样本data和聚类数k;
(1) 初始化。随机选取k个样本点作为初始聚类中心;
(2)对样本进行聚类。计算样本
到每个聚类中心的距离,将该样本指派到与其最近的聚类中心的类去。

(3)计算新的聚类中心。对于聚类结果
,计算当前类中各个样本的均值作为新的聚类中心。

(4)如果迭代收敛(新旧聚类中心不变)或符合迭代条件,输出并结束;否则,继续回到步(2)。

给出python代码

import numpy as np
import random 
import matplotlib.pyplot as plt 

def distance(point1, point2):  # 计算距离(欧几里得距离)
    return np.sqrt(np.sum((point1 - point2) ** 2))

def k_means(data, k, max_iter=500):
    centers = {}  # 初始聚类中心
    # 初始化,选k个样本作为初始聚类中心
    # random.sample(): 随机不重复抽取k个值
    for idx, i in enumerate(random.sample(range(data.shape[0]), k)):
        # idx取值范围[0, k-1],代表第几个聚类中心;  i为随机选取的样本作为聚类中心
        centers[idx] = data[i]  
    # 开始迭代
    for i in range(max_iter):  # 迭代次数
        print("开始第{}次迭代".format(i+1))
        clusters = {}    # 聚类结果,聚类中心的索引idx -> [样本集合]
        for i in range(k):  # 初始化为空列表
            clusters[i] = []
            
        for row in data:  # 遍历每个样本
            distances = []  # 计算该样本到每个聚类中心的距离 (只会有k个元素)
            for c in centers:  # 遍历每个聚类中心
                # 添加该样本点到聚类中心的距离
                distances.append(distance(row, centers[c])) 
            idx = np.argmin(distances)  # 最小距离的索引
            clusters[idx].append(row)   # 将该样本添加到第idx个聚类中心
            
        pre_centers = centers.copy()  # 记录之前的聚类中心点

        for c in clusters.keys():
            # 重新计算中心点(计算该聚类中心的所有样本的均值)
            centers[c] = np.mean(clusters[c], axis=0)  
  
        optimize = True
        for c in centers:
            if distance(pre_centers[c], centers[c]) > 1e-8:  # 中心点是否变化
                optimize = False
                break
        if optimize == True:  
            # 如果新旧聚类中心不变,则迭代停止
            break
    return centers, clusters

def predict(p_data, centers):  # 预测新样本点所在的类
    # 计算p_data 到每个聚类中心的距离,然后返回距离最小所在的聚类。
    distances = [distance(p_data, centers[c]) for c in centers]  
    return np.argmin(distances)

测试

随机生成200个样本点,维度为2,聚为3类;

77f22e44e5f128b4a01c35de4ed8d9c8.png

聚类输出

c73ad58e5fe02c180c4bd82a668ebdad.png

可视化聚类输出

6124064ebbb32d5880bcae59fe9cd78c.png

-完结-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值