K-均值聚类算法是一种常用的无监督学习算法,用于将数据集分成 K 个簇。该算法的主要思想是通过迭代的方式将数据点分配到离它们最近的簇中,并更新簇的中心点,直到满足某个停止条件为止。
以下是 K-均值聚类算法的基本步骤:
-
初始化:选择 K 个初始簇中心点。可以随机选择数据集中的 K 个点作为初始中心,或者使用一些启发式方法进行初始化。
-
分配数据点到最近的簇:对于每个数据点,计算它与各个簇中心点的距离,然后将其分配到距离最近的簇中。
-
更新簇的中心点:对于每个簇,重新计算其中心点,通常是该簇所有数据点的平均值。
-
重复步骤2和3:重复步骤2和3直到满足停止条件,例如簇的中心点不再发生变化,或者达到了预先设定的迭代次数。
K-均值聚类算法的优点包括简单易实现、计算复杂度较低,适用于大型数据集。然而,它也有一些缺点,例如对初始中心点的敏感性较高,可能收敛到局部最优解,且需要事先确定簇的数量 K。
在实际应用中,K-均值聚类算法常用于数据压缩、图像分割、文本挖掘等领域。
按密度聚类
代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler# 导入葡萄酒数据集
wine = load_wine()
X = wine.data
y = wine.target
feature_names = wine.feature_names# 数据标准化
X = StandardScaler().fit_transform(X)# 使用K均值算法进行聚类
kmeans = KMeans(n_clusters=3, random_state=42)
clusters = kmeans.fit_predict(X)# 计算轮廓系数
silhouette_avg = silhouette_score(X, clusters)
print("轮廓系数:", silhouette_avg)# 绘制散点图
plt.figure(figsize=(10, 6))# 根据不同的聚类结果绘制散点图
for i in range(3):plt.scatter(X[clusters == i, 0], X[clusters == i, 1], label=f'聚类 {i}')# 绘制聚类中心
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], marker='*', s=200, c='black', label='聚类中心')# 添加标题和标签
plt.title('葡萄酒数据集的K均值聚类')
plt.xlabel(feature_names[0])
plt.ylabel(feature_names[1])
plt.legend()
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 显示图形
plt.show()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split# 导入葡萄酒数据集
wine = load_wine()
X = wine.data
y = wine.target
feature_names = wine.feature_names# 数据标准化
X = StandardScaler().fit_transform(X)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 使用K均值算法进行聚类
kmeans = KMeans(n_clusters=3, random_state=42)
clusters = kmeans.fit_predict(X_train)# 计算轮廓系数
silhouette_avg = silhouette_score(X_train, clusters)
print("训练集轮廓系数:", silhouette_avg)# 使用测试集进行预测
test_clusters = kmeans.predict(X_test)# 计算准确度
accuracy = accuracy_score(y_test, test_clusters)
print("测试集准确度:", accuracy)# 绘制分布散点图
plt.figure(figsize=(12, 6))# 绘制训练集分布散点图
plt.subplot(1, 2, 1)
for i in range(3):plt.scatter(X_train[clusters == i, 0], X_train[clusters == i, 1], label=f'聚类 {i}')plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], marker='*', s=200, c='black', label='聚类中心')
plt.title('训练集分布散点图')
plt.xlabel(feature_names[0])
plt.ylabel(feature_names[1])
plt.legend()# 绘制测试集预测折线图
plt.subplot(1, 2, 2)
plt.plot(range(len(X_test)), test_clusters, marker='o', linestyle='-', color='b', label='预测值')
plt.plot(range(len(X_test)), y_test, marker='x', linestyle='--', color='r', label='真实值')
plt.title('测试集预测折线图')
plt.xlabel('样本编号')
plt.ylabel('类别')
plt.legend()# 显示图形
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.tight_layout()
plt.show()
按层次聚类-从上到下
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import silhouette_score, accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split# 导入葡萄酒数据集
wine = load_wine()
X = wine.data
y = wine.target
feature_names = wine.feature_names# 数据标准化
X = StandardScaler().fit_transform(X)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 使用层次聚类算法进行聚类
agg_clustering = AgglomerativeClustering(n_clusters=3)
clusters = agg_clustering.fit_predict(X_train)# 计算轮廓系数
silhouette_avg = silhouette_score(X_train, clusters)
print("训练集轮廓系数:", silhouette_avg)# 使用测试集进行预测
test_clusters = agg_clustering.fit_predict(X_test)# 计算准确度
accuracy = accuracy_score(y_test, test_clusters)
print("测试集准确度:", accuracy)# 绘制分布散点图
plt.figure(figsize=(12, 6))# 绘制训练集分布散点图
plt.subplot(1, 2, 1)
for i in range(3):plt.scatter(X_train[clusters == i, 0], X_train[clusters == i, 1], label=f'聚类 {i}')plt.title('训练集分布散点图')
plt.xlabel(feature_names[0])
plt.ylabel(feature_names[1])
plt.legend()# 绘制测试集预测折线图
plt.subplot(1, 2, 2)
plt.plot(range(len(X_test)), test_clusters, marker='o', linestyle='-', color='b')
plt.plot(range(len(X_test)), y_test, marker='x', linestyle='--', color='r', label='真实值')
plt.title('测试集预测折线图')
plt.xlabel('样本编号')
plt.ylabel('类别')# 显示图形
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.tight_layout()
plt.show()
按层次聚类-从下到上
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import silhouette_score, accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split# 导入葡萄酒数据集
wine = load_wine()
X = wine.data
y = wine.target
feature_names = wine.feature_names# 数据标准化
X = StandardScaler().fit_transform(X)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 使用层次聚类算法进行聚类
agg_clustering = AgglomerativeClustering(n_clusters=3, linkage='ward')
clusters = agg_clustering.fit_predict(X_train)# 计算轮廓系数
silhouette_avg = silhouette_score(X_train, clusters)
print("训练集轮廓系数:", silhouette_avg)# 使用测试集进行预测
test_clusters = agg_clustering.fit_predict(X_test)# 计算准确度
accuracy = accuracy_score(y_test, test_clusters)
print("测试集准确度:", accuracy)# 绘制分布散点图
plt.figure(figsize=(12, 6))# 绘制训练集分布散点图
plt.subplot(1, 2, 1)
for i in range(3):plt.scatter(X_train[clusters == i, 0], X_train[clusters == i, 1], label=f'聚类 {i}')plt.title('训练集分布散点图')
plt.xlabel(feature_names[0])
plt.ylabel(feature_names[1])
plt.legend()# 绘制测试集预测折线图
plt.subplot(1, 2, 2)
plt.plot(range(len(X_test)), test_clusters, marker='o', linestyle='-', color='b')
plt.plot(range(len(X_test)), y_test, marker='x', linestyle='--', color='r', label='真实值')
plt.title('测试集预测折线图')
plt.xlabel('样本编号')
plt.ylabel('类别')
plt.legend()# 显示图形
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.tight_layout()
plt.show()
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target# 使用PCA进行降维
pca = PCA(n_components=2) # 降维到2维
X_pca = pca.fit_transform(X)# 创建KMeans模型
kmeans = KMeans(n_clusters=3, random_state=42)# 在降维后的数据上进行聚类
kmeans.fit(X_pca)# 获取聚类结果
labels = kmeans.labels_# 绘制聚类结果
plt.figure(figsize=(10, 6))
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=labels, cmap=plt.cm.Set1)
plt.title('K-Means Clustering of Iris Dataset')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()
K-均值聚类算法是一种常用的无监督学习算法,用于将数据集分成 K 个相似的组或者簇。以下是 K-均值聚类算法的优缺点:
优点:
- 简单易实现:K-均值算法相对简单,易于理解和实现,是一种常用的聚类算法。
- 计算速度快:对于大型数据集来说,K-均值算法通常执行速度较快,适用于大规模数据集的聚类任务。
- 适用于均衡分布的簇:当簇的形状大致相似且大小差异不大时,K-均值算法表现较好。
- 可扩展性强:K-均值算法适用于大多数数据类型,可以灵活地应用于不同的领域和问题。
缺点:
- 需要预先确定聚类数目 K:K-均值算法需要提前指定聚类的数量 K,而且对初始聚类中心的选择非常敏感,不同的初始值可能导致不同的聚类结果。
- 对初始值敏感:算法的结果受初始聚类中心的影响,不同的初始值可能导致不同的聚类结果,因此需要进行多次运行以选择最佳的结果。
- 对异常值敏感:K-均值算法对异常值(离群点)比较敏感,可能会影响最终的聚类结果。
- 只适用于凸形簇:K-均值算法假设簇是凸形的,当簇的形状不规则或者大小差异较大时,可能导致聚类效果较差。