Python实现KMeans聚类算法详解

1. 简介

KMeans算法是一种常用的聚类算法,它能够将数据集中的样本点划分到不同的簇中,使得同一簇内的样本点相似度较高,而不同簇之间的样本点相似度较低。本文将使用Python从零实现KMeans算法,并提供详细的代码解释和示例。

2. 算法步骤

KMeans算法的步骤如下:

  1. 随机初始化K个聚类中心。
  2. 计算每个样本点到各个聚类中心的距离,并将样本点分配到距离最近的聚类中心所在的簇中。
  3. 重新计算每个簇的中心点,作为新的聚类中心。
  4. 重复步骤2和步骤3,直到聚类中心不再发生变化或达到最大迭代次数。

3. 代码实现

import scipy.io as sio # load mat
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans

# 生成随机的k个中心
def random_init(data, k):
    # data:数据集 k:聚类中心个数
    # 返回 k 个聚类中心并转换成array数组
    return data.sample(k).values

# 单个找寻聚类
def find_cluster(x, centroids):
    # x:待聚类点坐标  centroids:中心坐标
    distances = np.apply_along_axis(func1d=np.linalg.norm, axis=1, arr=centroids-x)
    return np.argmin(distances)

# 集体data聚类标签
def assign_cluster(data, centroids):
    return np.apply_along_axis(lambda x: find_cluster(x, centroids), axis=1, arr=data.values)

#  data中增加一列聚类标签C
def combineDataC(data, C):
    dataC = data.copy()
    dataC['C'] = C
    return dataC

# 新中心点,同时去掉C, 再转换成array数组
def newCentroids(data, C):
    dataC = combineDataC(data, C)
    return dataC.groupby('C', as_index=False).mean().sort_values(by='C').drop('C', axis=1).values

# 损失函数
def cost(data, centroids, C):
    # data:数据集 centroids:中心坐标 C:聚类标签
    m = data.shape[0] # 样本量
    dataCentroids = centroids[C] # 各行的中心坐标
    distances = np.apply_along_axis(func1d=np.linalg.norm, axis=1, arr=data-dataCentroids)
    return distances.sum()/m

# kmeans通道,运行一次
def kMeansIter(data, k, epoch=100, tol=0.0001):
    # 生成最初的中心坐标
    centroids = random_init(data, k)

    costProgress = []  # 用来存放递归聚类的每次损失
    # 分配聚类标签
    for i in range(epoch):
        C = assign_cluster(data, centroids)
        centroids = newCentroids(data, C)
        costProgress.append(cost(data, centroids, C))

        if len(costProgress) > 1:
            if np.abs(costProgress[-1] - costProgress[-2]) / costProgress[-1] < tol:
                break

    return C, centroids, costProgress[-1]

# 每个k运行n_init次,套用kmeans通道
def kMeans(data, k, epoch=100, n_init=10):
    tries = np.array([kMeansIter(data, k) for _ in range(n_init)])
    leasrCostIndex = np.argmin(tries[:, -1])
    return tries[leasrCostIndex]

4. 代码解释

4.1 random_init(data, k) 函数

该函数用于随机初始化K个聚类中心。

  • data: 数据集
  • k: 聚类中心个数
  • 返回值: k个聚类中心

4.2 find_cluster(x, centroids) 函数

该函数用于找到距离样本点x最近的聚类中心。

  • x: 待聚类点坐标
  • centroids: 中心坐标
  • 返回值: 最近聚类中心的索引

4.3 assign_cluster(data, centroids) 函数

该函数为数据集中的每个样本点分配聚类标签。

  • data: 数据集
  • centroids: 聚类中心
  • 返回值: 聚类标签数组

4.4 combineDataC(data, C) 函数

该函数将聚类标签添加到数据集中。

  • data: 数据集
  • C: 聚类标签
  • 返回值: 带有聚类标签的数据集

4.5 newCentroids(data, C) 函数

该函数根据当前的聚类结果计算新的聚类中心。

  • data: 数据集
  • C: 聚类标签
  • 返回值: 新的聚类中心

4.6 cost(data, centroids, C) 函数

该函数计算当前聚类结果的损失值。

  • data: 数据集
  • centroids: 聚类中心
  • C: 聚类标签
  • 返回值: 损失值

4.7 kMeansIter(data, k, epoch, tol) 函数

该函数执行一次完整的KMeans迭代。

  • data: 数据集
  • k: 聚类中心个数
  • epoch: 最大迭代次数
  • tol: 收敛阈值
  • 返回值: 聚类标签、聚类中心、损失值

4.8 kMeans(data, k, epoch, n_init) 函数

该函数多次执行KMeans算法,并选择损失值最小的结果。

  • data: 数据集
  • k: 聚类中心个数
  • epoch: 最大迭代次数
  • n_init: 算法执行次数
  • 返回值: 最优的聚类标签、聚类中心、损失值

5. 示例

# 导入数据
data = pd.read_csv('data.csv')

# 设置聚类中心个数
k = 3

# 执行KMeans算法
C, centroids, cost = kMeans(data, k)

# 打印聚类结果
print('聚类标签:', C)
print('聚类中心:', centroids)
print('损失值:', cost)

6. 总结

本文使用Python从零实现了KMeans聚类算法,并提供了详细的代码解释和示例。希望本文能够帮助你理解KMeans算法的原理,并将其应用于实际数据分析中。

Python实现KMeans聚类算法详解

原文地址: https://www.cveoy.top/t/topic/jUSF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录