Python实现K-means聚类算法
K-means聚类算法是一种常用的无监督学习算法,它的主要思想是将数据集划分为K个簇,使得同一簇内的数据点相似度较高,不同簇之间的数据点相似度较低。本文将详细讲解如何使用Python实现K-means聚类算法,并提供两个示例说明。
K-means聚类算法原理
K-means聚类算法的基本思想是从数据集中随机选择K个点作为初始的聚类中心,然后将每个数据点分配到距离最近的聚类中心所在的簇中,再重新计算每个簇的聚类中心,直到聚类中心不再发生变化或达到最大迭代次数为止。具体来说,算法的步骤如下:
- 随机选择K个点作为初始的聚类中心;
- 将每个数据点分配到距离最近的聚类中心所在的簇中;
- 重新计算每个簇的聚类中心;
- 如果聚类中心不再发生变化或达到最大迭代次数,则停止迭代,否则返回步骤2。
其中,距离通常采用欧氏距离或曼哈顿距离来计算。
Python实现K-means聚类算法
在Python中,我们可以使用NumPy库和Matplotlib库来实现K-means聚类算法。下面是一个简单的示例代码,用于对二维数据进行聚类。
import numpy as np
import matplotlib.pyplot as plt
# 定义K-means聚类算法
def kmeans(X, K, max_iters=100):
# 随机选择K个点作为初始的聚类中心
centers = X[np.random.choice(len(X), K, replace=False)]
for i in range(max_iters):
# 将每个数据点分配到距离最近的聚类中心所在的簇中
labels = np.argmin(((X[:, np.newaxis, :] - centers)**2).sum(axis=2), axis=1)
# 重新计算每个簇的聚类中心
new_centers = np.array([X[labels == k].mean(axis=0) for k in range(K)])
# 如果聚类中心不再发生变化,则停止迭代
if np.allclose(centers, new_centers):
break
centers = new_centers
return labels, centers
# 生成随机的二维数据
np.random.seed(0)
X = np.random.randn(100, 2)
# 运行K-means聚类算法
K = 3
labels, centers = kmeans(X, K)
# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.scatter(centers[:, 0], centers[:, 1], marker='x', s=200, linewidths=3, color='r')
plt.show()
在这个示例中,我们首先生成了随机的二维数据X。然后,我们定义了K-means聚类算法kmeans,其中X是数据集,K是簇的个数,max_iters是最大迭代次数。接下来,我们运行K-means聚类算法,对二维数据进行聚类,并返回每个数据点所属的簇和每个簇的聚类中心。最后,我们使用Matplotlib库可视化结果,将数据点和聚类中心绘制在同一张图上。
示例1:使用K-means聚类算法对图像进行分割
在这个示例中,我们将使用K-means聚类算法对图像进行分割。图像分割是一种常用的图像处理技术,其目标是将图像分成若干个区域,使得同一区域内的像素具有相似的特征,不同区域之间的像素具有明显的差异。
import numpy as np
import matplotlib.pyplot as plt
from skimage import io
# 定义K-means聚类算法
def kmeans(X, K, max_iters=100):
# 随机选择K个点作为初始的聚类中心
centers = X[np.random.choice(len(X), K, replace=False)]
for i in range(max_iters):
# 将每个数据点分配到距离最近的聚类中心所在的簇中
labels = np.argmin(((X[:, np.newaxis, :] - centers)**2).sum(axis=2), axis=1)
# 重新计算每个簇的聚类中心
new_centers = np.array([X[labels == k].mean(axis=0) for k in range(K)])
# 如果聚类中心不再发生变化,则停止迭代
if np.allclose(centers, new_centers):
break
centers = new_centers
return labels, centers
# 读取图像数据
image = io.imread('lena.png')
# 将图像数据转换为二维数组
X = image.reshape(-1, 3)
# 运行K-means聚类算法
K = 16
labels, centers = kmeans(X, K)
# 将每个像素点的颜色替换为所属簇的聚类中心的颜色
X_new = centers[labels].astype(np.uint8)
# 将二维数组转换为图像数据
image_new = X_new.reshape(image.shape)
# 可视化结果
fig, ax = plt.subplots(1, 2, figsize=(8, 4))
ax[0].imshow(image)
ax[0].set(title='Original image')
ax[1].imshow(image_new)
ax[1].set(title='Segmented image')
plt.show()
在这个示例中,我们首先读取了一张图像数据,并将其转换为二维数组X。然后,我们运行K-means聚类算法,对图像数据进行分割,并将每个像素点的颜色替换为所属簇的聚类中心的颜色。最后,我们将二维数组转换为图像数据,并使用Matplotlib库可视化结果,将原始图像和分割后的图像绘制在同一张图上。
示例2:使用K-means聚类算法对手写数字进行分类
在这个示例中,我们将使用K-means聚类算法对手写数字进行分类。手写数字分类是一个经典的机器学习问题,其目标是将手写数字图像分成10个类别,分别对应数字0到9。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
# 定义K-means聚类算法
def kmeans(X, K, max_iters=100):
# 随机选择K个点作为初始的聚类中心
centers = X[np.random.choice(len(X), K, replace=False)]
for i in range(max_iters):
# 将每个数据点分配到距离最近的聚类中心所在的簇中
labels = np.argmin(((X[:, np.newaxis, :] - centers)**2).sum(axis=2), axis=1)
# 重新计算每个簇的聚类中心
new_centers = np.array([X[labels == k].mean(axis=0) for k in range(K)])
# 如果聚类中心不再发生变化,则停止迭代
if np.allclose(centers, new_centers):
break
centers = new_centers
return labels, centers
# 加载手写数字数据集
digits = load_digits()
# 运行K-means聚类算法
K = 10
labels, centers = kmeans(digits.data, K)
# 可视化结果
fig, ax = plt.subplots(2, 5, figsize=(8, 4))
for i in range(10):
ax[i//5, i%5].imshow(centers[i].reshape(8, 8), cmap='gray')
ax[i//5, i%5].set(title=str(i))
plt.show()
在这个示例中,我们首先加载了手写数字数据集digits。然后,我们运行K-means聚类算法,对手写数字进行分类,并返回每个手写数字所属的类别和每个类别的聚类中心。最后,我们使用Matplotlib库可视化结果,将每个类别的聚类中心绘制在不同的子图上。
总结
本文详细讲解了如何使用Python实现K-means聚类算法,并提供了两个示例说明。K-means聚类算法是一种常用的无监督学习算法,它的主要思想是将数据集划分为K个簇,使得同一簇内的数据点相似度较高,不同簇之间的数据点相似度较低。在实际应用中,我们可以根据具体的需求选择不同的距离度量和聚类中心初始化方法,并结合其他无监督学习算法进行综合处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:利用python实现聚类分析K-means算法的详细过程 - Python技术站