机器学习第九章-聚类

目录

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 进行层次聚类,并通过可视化结果和树状图来分析聚类效果

实验结果:

相关推荐
終不似少年遊*4 分钟前
美国加州房价数据分析01
人工智能·python·机器学习·数据挖掘·数据分析·回归算法
嘿嘻哈呀11 分钟前
使用ID3算法根据信息增益构建决策树
决策树·机器学习·信息增益·id3算法
GocNeverGiveUp2 小时前
机器学习1-简单神经网络
人工智能·机器学习
帅逼码农5 小时前
K-均值聚类算法
算法·均值算法·聚类
終不似少年遊*6 小时前
美国加州房价数据分析02
人工智能·python·机器学习·数据挖掘·数据分析·回归算法
三月七(爱看动漫的程序员)7 小时前
HiQA: A Hierarchical Contextual Augmentation RAG for Multi-Documents QA---附录
人工智能·单片机·嵌入式硬件·物联网·机器学习·语言模型·自然语言处理
MUTA️8 小时前
RT-DETR学习笔记(2)
人工智能·笔记·深度学习·学习·机器学习·计算机视觉
ROBOT玲玉9 小时前
Milvus 中,FieldSchema 的 dim 参数和索引参数中的 “nlist“ 的区别
python·机器学习·numpy
GocNeverGiveUp10 小时前
机器学习2-NumPy
人工智能·机器学习·numpy
浊酒南街10 小时前
决策树(理论知识1)
算法·决策树·机器学习