K-means聚类模型教程(个人总结版)

embedded/2024/10/22 17:38:02/

K-means聚类是一种广泛应用于数据挖掘和数据分析的无监督学习算法。它通过将数据点分成K个簇(cluster),使得同一簇内的数据点之间的相似度最大,不同簇之间的相似度最小。本文将详细介绍K-means聚类算法的背景、基本原理、具体实现步骤、算法优化方法、优劣势以及应用实例。

一、算法背景

1.1 聚类分析的历史

聚类分析是一种重要的数据分析技术,可以追溯到20世纪50年代。其目的是将数据集分成若干个簇,使得同一个簇内的数据点尽可能相似,不同簇的数据点尽可能不同。聚类分析在许多领域有广泛应用,如模式识别、图像分析、市场研究、生物信息学等。

1.2 K-means算法的提出

K-means算法最早由Hugo Steinhaus在1956年提出,并由Stuart Lloyd在1957年进一步发展。其核心思想是通过迭代优化,使得每个数据点所属的簇中心与其距离最小,从而实现数据的聚类。

二、K-means聚类的基本原理

K-means聚类算法的目标是通过最小化簇内数据点到簇中心(centroid)的平方距离,使得每个簇内的数据点尽可能接近簇中心。具体步骤如下:

  1. 选择K个初始簇中心
  2. 分配数据点到最近的簇中心
  3. 重新计算簇中心:对于每个簇,计算其所有数据点的平均值,作为新的簇中心。
  4. 重复步骤2和步骤3,直到簇中心不再变化或达到预定的迭代次数

三、K-means聚类的具体实现步骤

3.1 数据准备

在开始聚类之前,需要准备数据集。假设我们有一个二维数据集,每个数据点有两个特征。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs# 生成示例数据
X, y = make_blobs(n_samples=300, centers=4, random_state=42, cluster_std=0.60)# 可视化数据
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.show()

3.2 选择初始簇中心

初始化K个簇中心可以随机选择数据点或使用其他初始化方法(如K-means++)。

def initialize_centroids(X, k):indices = np.random.choice(X.shape[0], k, replace=False)return X[indices]# 初始化簇中心
k = 4
centroids = initialize_centroids(X, k)
print("Initial centroids:\n", centroids)

3.3 分配数据点到最近的簇中心

计算每个数据点到所有簇中心的距离,并将其分配到最近的簇中心。

def assign_clusters(X, centroids):distances = np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2))return np.argmin(distances, axis=0)# 分配数据点到最近的簇中心
labels = assign_clusters(X, centroids)
print("Initial cluster assignments:\n", labels)

3.4 重新计算簇中心

根据分配结果,计算每个簇的新中心。

def compute_centroids(X, labels, k):return np.array([X[labels == i].mean(axis=0) for i in range(k)])# 重新计算簇中心
new_centroids = compute_centroids(X, labels, k)
print("New centroids:\n", new_centroids)

3.5 迭代步骤

重复分配数据点和重新计算簇中心,直到簇中心不再变化或达到最大迭代次数。

def kmeans(X, k, max_iters=100):centroids = initialize_centroids(X, k)for _ in range(max_iters):labels = assign_clusters(X, centroids)new_centroids = compute_centroids(X, labels, k)if np.all(centroids == new_centroids):breakcentroids = new_centroidsreturn centroids, labels# 运行K-means聚类
centroids, labels = kmeans(X, k)
print("Final centroids:\n", centroids)# 可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')
plt.scatter(centroids[:, 0], centroids[:, 1], s=200, c='red', marker='X')
plt.show()

四、K-means聚类的优化方法

4.1 K-means++初始化

K-means++是一种改进的初始化方法,通过更好地选择初始簇中心,减少了K-means的收敛时间,提高了结果的稳定性。

from sklearn.cluster import KMeans# 使用K-means++初始化
kmeans = KMeans(n_clusters=k, init='k-means++', max_iter=300, n_init=10, random_state=42)
y_kmeans = kmeans.fit_predict(X)# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=200, c='red', marker='X')
plt.show()

4.2 确定最佳簇数

使用肘部法或轮廓系数等方法,可以帮助确定数据的最佳簇数。

4.2.1 肘部法

肘部法通过计算不同簇数下的总误差平方和(SSE),选择SSE下降速度减缓的点作为最佳簇数。

sse = []
for k in range(1, 11):kmeans = KMeans(n_clusters=k, init='k-means++', max_iter=300, n_init=10, random_state=42)kmeans.fit(X)sse.append(kmeans.inertia_)# 可视化肘部法
plt.plot(range(1, 11), sse, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('SSE')
plt.show()
4.2.2 轮廓系数

轮廓系数通过计算簇内和簇间的距离,评估不同簇数下的聚类效果。

from sklearn.metrics import silhouette_scoresilhouette_scores = []
for k in range(2, 11):kmeans = KMeans(n_clusters=k, init='k-means++', max_iter=300, n_init=10, random_state=42)y_kmeans = kmeans.fit_predict(X)silhouette_scores.append(silhouette_score(X, y_kmeans))# 可视化轮廓系数
plt.plot(range(2, 11), silhouette_scores, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Silhouette Score')
plt.show()

五、K-means聚类的优劣势

5.1 优势

  1. 简单易懂:K-means算法的基本思想简单直观,易于理解和实现。
  2. 计算效率高:对于大规模数据集,K-means算法的计算效率较高,适合快速聚类。
  3. 结果解释性强:聚类结果易于解释,可以直接通过簇中心和簇内数据点之间的关系进行分析。

5.2 劣势

  1. 对初始值敏感:K-means算法对初始簇中心的选择非常敏感,不同的初始值可能导致不同的聚类结果。
  2. 需要预先确定K值:K-means算法需要预先指定簇的数量K,这在实际应用中可能不容易确定。
  3. 对噪声和异常值敏感:K-means算法对数据中的噪声和异常值较为敏感,可能影响聚类结果的准确性。
  4. 适用数据类型有限:K-means算法主要适用于数值型数据,对于类别型数据或高维稀疏数据的效果不佳。

六、K-means聚类的应用实例

6.1 图像压缩

K-means聚类可以用于图像压缩,将图像像素分配到K个簇,从而减少颜色数量,实现图像压缩。

from skimage import io
from sklearn.utils import shuffle# 加载图像
image = io.imread('path/to/your/image.jpg')
image = np.array(image, dtype=np.float64) / 255# 将图像像素展开为二维数组
w, h, d = image.shape
image_array = np.reshape(image, (w * h, d))# 使用K-means进行图像压缩
k = 16
image_array_sample = shuffle(image_array, random_state=42)[:1000]
kmeans = KMeans(n_clusters=k, random_state=42).fit(image_array_sample)
labels = kmeans.predict(image_array)
compressed_image = kmeans.cluster_centers_[labels].reshape(w, h, d)# 显示压缩后的图像
plt.imshow(compressed_image)
plt.show()

6.2 客户细分

K-means聚类可以用于客户细分,根据客户的购买行为、人口统计数据等,将客户分成不同的簇,帮助企业进行精准营销。

import pandas as pd# 加载客户数据
data = pd.read_csv('path/to/your/customer_data.csv')# 选择特征进行聚类
X = data[['Annual Income (k$)', 'Spending Score (1-100)']]# 使用K-means进行客户细分
kmeans = KMeans(n_clusters=5, random_state=42)
y_kmeans = kmeans.fit_predict(X)# 可视化客户细分结果
plt.scatter(X.iloc[:, 0], X.iloc[:, 1], c=y_kmeans, s=50, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=200, c='red', marker='X')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.show()

七、总结

K-means聚类是一种简单高效的无监督学习算法,广泛应用于图像处理、市场营销、客户细分等领域。通过详细介绍K-means聚类的基本原理、具体实现步骤、算法优化方法和应用实例,希望能帮助读者更好地理解和应用这一重要的机器学习技术。在实际应用中,选择合适的簇数和初始化方法,并结合具体问题的需求进行调整和优化,将有助于获得更好的聚类效果。

参考文献

为了深入理解和应用K-means聚类算法,建议参考以下资料:

  1. 《机器学习》 - 周志华
  2. 《模式分类》 - Duda, Hart, Stork
  3. 《数据挖掘:概念与技术》 - Han, Kamber, Pei
  4. K-means++: The Advantages of Careful Seeding - Arthur, Vassilvitskii (2007)
  5. A Comparison of the K-means and K-medoids Algorithms - Park, Jun (2009)

这些资料将提供更深入的理论背景和实践指南,帮助读者进一步掌握K-means聚类算法及其应用。


http://www.ppmy.cn/embedded/42299.html

相关文章

Java基础(三)- 多线程、网络通信、单元测试、反射、注解、动态代理

多线程基础 线程:一个程序内部的一条执行流程,只有一条执行流程就是单线程 java.lang.Thread代表线程 主线程退出,子线程存在,进程不会退出 可以使用jconsole查看 创建线程 有多个方法可以创建线程 继承Thread类 优点&#x…

PyQt5 中的 List View

文章目录 1. 基础概念2. 创建 List View2.1 PyQt5 中一个简单的 List View 实例2.2 代码解释2.3 运行结果 3. 数据模型3.1 标准模型3.2 自定义模型 4. 自定义 List View4.1 使用样式表 (QSS)4.2 设置项委托 (Item Delegate) 5.事件处理6. 与数据交互6.1 添加数据6.2 删除数据6.…

高中数学:平面向量-正交分解、坐标表示、坐标运算

一、正交分解 二、坐标表示 这里注意一点 坐标A(x,y)与向量 a → \mathop{a}\limits ^{\rightarrow} a→的坐标记作: a → \mathop{a}\limits ^{\rightarrow} a→(x,y),表示方式的区别 引申 三、加减运算的坐标表示 四、数乘运算的坐标表示 引申 两向量…

零基础学Java第十五天之正则表达式的初步理解

正则表达式的使用和理解 1、理解 正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的文本处理工具,它使用一种特定的模式来描述、匹配和操作文本字符串。正则表达式可以被用来检查一个字符串是否匹配某种模式&…

C语言游戏实战(12):植物大战僵尸(坤版)

植物大战僵尸 前言: 本游戏使用C语言和easyx图形库编写,通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧,以及锻炼我们独立的项目开发能力, 在开始编写代码之前,我们需要先了解一下游戏的基本规则…

40-2 了解与安装堡垒机

堡垒机 一、堡垒机与 JumpServer 1. 堡垒机 定义: 堡垒机(Bastion Host)是一种网络安全设备,用于保障网络和数据不受外部和内部用户的入侵和破坏。它通过各种技术手段监控和记录运维人员对网络内各种设备的操作行为,以便集中报警、及时处理和审计定责。功能: 权限控制:…

水平垂直居中的六种方法

1. 使用 Flexbox Flexbox 是一个现代的布局模型,可以轻松实现元素的水平和垂直居中。 .container {display: flex;justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */height: 100vh; /* 视窗高度 */ }2. 使用 Grid CSS Grid 是另一种强…

31.@Anonymous

1►@Anonymous原理 大家应该已经习惯我的教学套路,很多时候都是先使用,然后讲述原理。 上节课我们使用了注解@Anonymous,然后接口就可以直接被访问到了,不用token!不用token!不用token!。 我们一般知道,注解是给程序看的,给机器看的,当然也是给程序员看的。注解如果…