机器学习第九章-聚类

目录

9.1聚类任务

9.2性能度量

9.3距离计算

9.4圆形聚类

9.4.1k均值算法

9.4.2学习向量量化法(LVQ)

9.4.3高斯混合聚类

9.5密度聚类

9.6层次聚类


9.1聚类任务

在"无监督学习"中研究最多、应用最广的是"聚类" .聚类试图将数据集中的样本划分为若干个通常是不相交的子集,每个子集称为一个"簇" .聚类过程仅能自动形成簇结构,簇所对应的概念语义需由使用者来把握和命名。聚类的结果可用包含m个元素的簇标记向量 λ=(λ1;λ2;... ;λm) 表示.

9.2性能度量

聚类性能度量亦称聚类"有效性指标"聚类性能度量大致有两类. 一类是将聚类结果与某个"参考模型" 进行比较,称为"外部指标" ; 另一类是直接考察聚类结果而不利用任何参考模型,称为"内部指标" 。

聚类性能度量外部指标有如下:
Jaccard 系数(计算聚类结果与参考模型之间的交集与并集的比值) :
FM 指数(计算聚类结果与参考模型之间的精确度和召回率的调和平均数) :
Rand 指数(计算聚类结果与参考模型之间的一致决策和不一致决策的比值)
上述性能度量的结果值均在 [0 1] 区间,值越大越好.
聚类性能度量内部指标有如下:
**DB 指数 (**通过衡量各个簇的紧密度和分离度来评估聚类的效果):

Du nn 指数(通过比较簇内的紧密度和簇间的分离度来评估聚类的质量):

DBI 的值越小越好,而 DI 则相反,值越大越好.

9.3距离计算

对函数 dist(. ,.),若它是一个"距离度量" (distance measure) ,则需满足一 些基本性质:

非负性: dist(Xi , Xj) >= 0 ;
同一性: dist(Xi , Xj)=0当且仅当 Xi = Xj ;
对称性: dist(Xi , Xj)) = dist(xj , Xi) ;
直递性: dist(Xi , Xj) <= dist(Xi , Xk) + dist(Xk,X j*)*
最常用的是 "闵可夫斯基距离": ,p>=1
p=2 时,闵可夫斯基距离即欧氏距离:
p=1 时,闵可夫斯基距离即曼哈顿距离:
我们常将属性划分为"连续属性" 和"离散属性" ,前者在定义域上有无穷多个可能的取值,后者在定义域上是有限个取值.
对无序属性可采用 VDM,表示在属性 u上取值为a 的样本数, 表示在第i个样本簇
中在属性u 上取值为a 的样本数 ,k 为样本簇数,则属性u 上两个离散值a,b之间的 VDM 距离为:

当样本空间中不同属性的重要 性不同时 ,可使用" 加权距 离", 以加权闵 可夫 斯基距离为 例:

9.4圆形聚类

算法先对原型进行初始化,然后对原型进行迭代更新求解.采用不同的原型表示、不同的求解方式,将产生不同的算法.

9.4.1k均值算法

给定样本集 "k 均值" 算法针对聚类所得簇划分 最小化平方误差:

步骤如下:

  1. 选择K值:确定要分成的簇的数量K。

  2. 初始化中心:随机选择K个点作为初始簇中心(质心)。

  3. 分配簇:将每个数据点分配到距离其最近的簇中心所属的簇。

  4. 更新中心:重新计算每个簇的质心,质心是簇中所有点的均值。

  5. 重复迭代:重复步骤3和步骤4,直到簇中心不再发生显著变化,或者达到预设的迭代次数。

  6. 停止 :算法结束时,簇的划分稳定,所有点被划分到其最终的簇中。

下面是关于k均值算法的实验过程及分析结果:

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

# 生成样本数据
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# 执行K均值算法
kmeans = KMeans(n_clusters=4)
kmeans.fit(X)

# 获取簇中心和每个点的簇标签
centers = kmeans.cluster_centers_
labels = kmeans.labels_

# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='X')
plt.title('K-Means Clustering')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()

分析:

1.数据生成:生成了300个样本数据,划分为4个簇,每个簇的标准差为0.60。

2.K均值算法:对这些数据执行了K均值聚类,指定了4个簇。

3.可视化:结果图展示了数据点按簇进行着色,簇中心以红色"X"标记。

通过运行代码,可以直观地看到数据点如何被聚类到4个不同的簇中,以及每个簇的中心位置。这有助于验证K均值算法在实际数据上的效果。

实验结果:

9.4.2学习向量量化法(LVQ)

LVQ 假设数据样本带有类别标记,学习过程利用样本的这些监督信息来辅助聚类。

步骤如下:

  1. 初始化:从训练数据中随机选择若干样本点作为初始的原型向量(或质心),这些原型向量的数量通常等于类别数。

  2. 分配类别:为每个原型向量分配一个类别标签,通常是其所属的训练样本的类别。

  3. 训练过程:对每个训练样本:

    • 更新原型
      • 如果样本点的真实类别与最近原型的类别相同,则将原型向量向样本点移动(调整原型向量的位置)。
      • 如果样本点的真实类别与最近原型的类别不同,则将原型向量远离样本点移动。
    • 选择最近原型:找到距离样本点最近的原型向量,并确定其类别标签。
    • 计算距离:计算样本点到所有原型向量的距离。
  4. 重复训练:重复步骤3,直到原型向量的位置稳定,或者达到预设的训练次数。

  5. 分类 :使用训练好的原型向量对新样本进行分类:计算新样本与所有原型向量的距离,并将样本分配给距离最近的原型的类别

学习向量量化的实验过程及分析结果如下:

python 复制代码
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler

class LVQ:
    def __init__(self, n_prototypes):
        self.n_prototypes = n_prototypes

    def fit(self, X, y, n_iter=100, lr=0.01):
        self.classes = np.unique(y)
        self.prototypes = np.zeros((self.n_prototypes, X.shape[1]))
        self.labels = np.zeros(self.n_prototypes, dtype=int)
        
        # Initialize prototypes randomly
        for i in range(self.n_prototypes):
            idx = np.random.choice(len(X))
            self.prototypes[i] = X[idx]
            self.labels[i] = y[idx]
        
        for _ in range(n_iter):
            for i, x in enumerate(X):
                dists = np.linalg.norm(x - self.prototypes, axis=1)
                closest_idx = np.argmin(dists)
                if y[i] == self.labels[closest_idx]:
                    self.prototypes[closest_idx] += lr * (x - self.prototypes[closest_idx])
                else:
                    self.prototypes[closest_idx] -= lr * (x - self.prototypes[closest_idx])

    def predict(self, X):
        dists = np.linalg.norm(X[:, np.newaxis] - self.prototypes, axis=2)
        closest_idx = np.argmin(dists, axis=1)
        return self.labels[closest_idx]

# Load Iris dataset
data = load_iris()
X = data.data
y = data.target

# Standardize the features
scaler = StandardScaler()
X = scaler.fit_transform(X)

# Split into training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Initialize and train LVQ model
model = LVQ(n_prototypes=10)
model.fit(X_train, y_train)

# Predict and evaluate
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

print(f'准确率: {accuracy:.2f}')

分析:

这个实现没有依赖于 sklearn_lvq 库,而是手动实现了 LVQ 算法。使用了 numpyscikit-learn 进行数据处理和评估。

  1. 初始化 LVQ 类 :定义 LVQ 类及其方法。
  2. 训练模型:初始化原型,更新原型的位置。
  3. 预测和评估:通过计算距离并预测类别,评估模型性能。

实验结果:

9.4.3高斯混合聚类

高斯混合聚类采用概率模型来表达聚类原型。对n维样本空间X中的随机向量 x,若x服从高斯分布,其概率密度函数为:

步骤如下:

  1. 初始化参数

  2. 期望步骤(E-Step)

  3. 最大化步骤(M-Step)

  4. 收敛性检查

  5. 结果解释

下面是关于高斯混合聚类算法的实验过程及分析结果:

python 复制代码
import numpy as np
from sklearn.mixture import GaussianMixture
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
n_samples = 300
C = np.array([[0.7, -0.7], [0.7, 0.7]])
X = np.dot(np.random.randn(n_samples, 2), C)

# 应用高斯混合模型
gmm = GaussianMixture(n_components=2, random_state=0)
gmm.fit(X)
labels = gmm.predict(X)

# 结果可视化
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis')
plt.title('GMM Clustering')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')

# 绘制高斯分布
ax = plt.gca()
x = np.linspace(X[:, 0].min(), X[:, 0].max(), 100)
y = np.linspace(X[:, 1].min(), X[:, 1].max(), 100)
X_grid, Y_grid = np.meshgrid(x, y)
Z = np.exp(gmm.score_samples(np.c_[X_grid.ravel(), Y_grid.ravel()]))
Z = Z.reshape(X_grid.shape)
contour = ax.contour(X_grid, Y_grid, Z, levels=5, cmap='Greys', alpha=0.5)
plt.colorbar(contour)
plt.show()

# 输出分析结果
print("GMM Converged:", gmm.converged_)
print("Number of Iterations:", gmm.n_iter_)
print("Means of the clusters:\n", gmm.means_)
print("Covariances of the clusters:\n", gmm.covariances_)

分析:

  1. 聚类可视化:散点图显示了数据点根据模型预测的簇标签进行着色。等高线图显示了高斯分布的轮廓。
  2. GMM 收敛状态 :通过 gmm.converged_ 判断模型是否收敛。
  3. 迭代次数gmm.n_iter_ 表示模型收敛的迭代次数。
  4. 均值和协方差gmm.means_gmm.covariances_ 提供了每个簇的均值和协方差矩阵。

这个代码和结果分析展示了高斯混合模型在二维数据上的应用。

实验结果:

9.5密度聚类

密度聚类算法从样本密度的角度来考察样本之间的可连接性,并基于可连接样本不断扩展聚类簇以获得最终的聚类结果.DBSCAN 是一种著名的密度聚类算法,它基于一组"邻域"参数来刻画样本分布的紧密程度.

DBSCAN算法步骤如下:

  1. 选择参数 :设置两个参数,eps(邻域的半径)和 min_samples(一个簇的最小样本数)。

  2. 遍历数据点 :对于数据集中的每一个点,计算其 eps 邻域内的点数。

  3. 密度检验

    • 如果邻域内点数大于或等于 min_samples,将该点标记为核心点,并形成一个新簇。
    • 否则,标记为噪声点(如果它在任何核心点的邻域内)。
  4. 扩展簇

    • 从核心点开始,递归地将所有密度可达的点加入到同一簇中。
    • 对于新加入的点,再检查其邻域,重复此过程直到所有密度可达的点被处理完。
  5. 重复:对数据集中尚未标记的点重复步骤2至4,直到所有点被处理完。

  6. 处理噪声:所有未被分配到任何簇的点被标记为噪声。

DBSCAN的优点是能够发现任意形状的簇,并能自动识别噪声点。

下面是关于DBSCAN算法的实验代码及分析结果:

python 复制代码
import numpy as np
from sklearn.cluster import DBSCAN
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons

# 生成示例数据
X, _ = make_moons(n_samples=300, noise=0.1, random_state=42)

# 应用 DBSCAN 算法
dbscan = DBSCAN(eps=0.3, min_samples=5)
labels = dbscan.fit_predict(X)

# 结果可视化
plt.figure(figsize=(8, 6))
unique_labels = np.unique(labels)
colors = plt.cm.get_cmap('viridis', len(unique_labels))

for label in unique_labels:
    mask = (labels == label)
    plt.scatter(X[mask, 0], X[mask, 1], c=[colors(label)], label=f'Cluster {label}' if label != -1 else 'Noise', s=50)

plt.title('DBSCAN Clustering')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.show()

# 输出分析结果
print("Cluster labels:", np.unique(labels))
print("Number of clusters found:", len(set(labels)) - (1 if -1 in labels else 0))
print("Number of noise points:", list(labels).count(-1))

分析结果:

  1. 聚类可视化

    散点图展示了通过 DBSCAN 聚类得到的结果。不同的颜色表示不同的簇,噪声点(未分配到任何簇的点)通常会被标记为单独的颜色。

  2. 簇标签

    np.unique(labels) 列出了所有簇标签。标签 -1 表示噪声点。

  3. 簇数量

    len(set(labels)) - (1 if -1 in labels else 0) 计算了簇的数量。-1 被排除在外,因为它代表噪声点,不属于任何簇。

  4. 噪声点数量

    list(labels).count(-1) 计算了噪声点的数量。

实验结果:

9.6层次聚类

层次聚类试图 不同层次对数据集进行划分,从而形成树聚类结构 ,数据集的划分采用"自 底向上 "的聚合策略,也可采 "自顶向下" 分拆策略.

AGNES 是一种采用自底 向上聚合策略的层次聚类算法.它先将数据集中的每个样本看作初始聚类簇,然后在算法运行的每一步中找出离最近的两个聚类簇进行合并,该过程不断重复,直至达到预设的聚类簇个数.

步骤如下:

  1. 初始化:将每个数据点视为一个单独的簇。

  2. 计算距离:计算所有簇之间的距离。初始时,距离是数据点之间的距离。

  3. 合并簇

    • 找到距离最小的两个簇,将它们合并成一个新的簇。
    • 更新簇间的距离。具体方法取决于距离度量,例如单链接、全链接或平均链接。
  4. 重复:重复步骤2和3,直到所有点被合并成一个簇或达到预定的簇数量。

  5. 停止条件:算法结束时,得到一个树状图(dendrogram),表示不同簇的合并过程。

下面是AGNES算法的实验代码和分析结果:

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_moons
import scipy.cluster.hierarchy as sch

# 生成示例数据
X, _ = make_moons(n_samples=300, noise=0.1, random_state=42)

# 应用 AGNES 算法(AgglomerativeClustering)
agnes = AgglomerativeClustering(n_clusters=2, linkage='ward')
labels = agnes.fit_predict(X)

# 结果可视化
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=50, edgecolor='k')
plt.title('Agglomerative Clustering (AGNES)')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()

# 生成树状图(dendrogram)
plt.figure(figsize=(10, 7))
dendrogram = sch.dendrogram(sch.linkage(X, method='ward'))
plt.title('Dendrogram for AGNES')
plt.xlabel('Sample index')
plt.ylabel('Distance')
plt.show()

# 输出分析结果
print("Cluster labels:", np.unique(labels))
print("Number of clusters found:", len(set(labels)))

分析结果:

  1. 聚类可视化

    散点图展示了通过 AGNES 聚类得到的结果。不同的颜色表示不同的簇,便于观察数据的分组情况。

  2. 树状图

    树状图展示了数据点合并的过程。每次合并操作都会在树状图上形成一个连接线,线的高度表示合并时的距离。通过观察树状图,可以确定不同簇的形成过程和距离。

  3. 簇标签

    np.unique(labels) 列出了所有簇的标签。与散点图中的颜色对应。

  4. 簇数量

    len(set(labels)) 计算了最终得到的簇的数量。这与在 AGNES 中设定的 n_clusters 参数一致。

这段代码展示了如何使用 AGNES 进行层次聚类,并通过可视化结果和树状图来分析聚类效果

实验结果:

相关推荐
开MINI的工科男1 小时前
深蓝学院-- 量产自动驾驶中的规划控制算法 小鹏
人工智能·机器学习·自动驾驶
AI大模型知识分享2 小时前
Prompt最佳实践|如何用参考文本让ChatGPT答案更精准?
人工智能·深度学习·机器学习·chatgpt·prompt·gpt-3
小言从不摸鱼4 小时前
【AI大模型】ChatGPT模型原理介绍(下)
人工智能·python·深度学习·机器学习·自然语言处理·chatgpt
Lossya9 小时前
【机器学习】参数学习的基本概念以及贝叶斯网络的参数学习和马尔可夫随机场的参数学习
人工智能·学习·机器学习·贝叶斯网络·马尔科夫随机场·参数学习
Trouvaille ~9 小时前
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧
图像处理·python·机器学习·numpy·信号处理·时间序列分析·科学计算
拓端研究室TRL9 小时前
TensorFlow深度学习框架改进K-means聚类、SOM自组织映射算法及上海招生政策影响分析研究...
深度学习·算法·tensorflow·kmeans·聚类
qq_5503379912 小时前
研1日记14
人工智能·深度学习·机器学习
i嗑盐の小F12 小时前
【IEEE&ACM Fellow、CCF组委】第三届人工智能与智能信息处理国际学术会议(AIIIP 2024)
人工智能·深度学习·算法·机器学习·自然语言处理·信号处理
大耳朵爱学习14 小时前
大模型预训练的降本增效之路——从信息密度出发
人工智能·深度学习·机器学习·自然语言处理·大模型·llm·大语言模型
FOUR_A15 小时前
【机器学习导引】ch2-模型评估与选择
人工智能·机器学习