[机器学习复习笔记] Clustering 聚类 (K-means实现)

Cluster (KMeans实现)

1. KMeans 介绍及符号说明

给定样本集 \(D = \{ \mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_m \}\)\(\text{KMeans}\) 算法针对聚类所得的簇划分 \(\mathcal C = \{ C_1, C_2, ..., C_k \}\)(分为 \(k\) 类) 最小化平方差:

  • 平方差
    其中 \(\mathbf{x}\) 为当前簇 \(C_i\) 中的样本向量,\(\mu_i\) 为簇 \(C_i\)均值向量

\[\begin{split} E &= \sum_{i = 1}^{k} \sum_{\mathbf{x} \in C_i} ||\mathbf{x} - \mathbf{\mu}_i||^2_2 \end{split} \]

  • 均值向量

\[\mathbf{\mu}_i = \frac{1}{|C_i|}\sum_{\mathbf{x} \in C_i} \mathbf{x} \]

  • 样本向量 \(\mathbf{x}_j\) 与均值向量 \(\mathbf{\mu}_i\) 之间的距离,\(d_{ji} = \text{dist}_f(\mathbf{x}_j, \mathbf{\mu}_i)\),其中函数 \(f\) 可以是 闵可夫斯基距离欧几里得距离 或者 曼哈顿距离

    • 闵可夫斯基距离

    \[\text{dist}_{\text{mk}}(\mathbf x_i, \mathbf x_j) = (\sum_{u = 1}^{d}|x_{iu} - x_{ju}|^p)^{\frac{1}{p}} \]

    • 欧几里得距离
      \(p\) 取2时,闵可夫斯基距离即为欧几里得距离

    \[\text{dist}_{\text{ed}}(\mathbf x_i, \mathbf x_j) = \sqrt{\sum_{u = 1}^{d}|x_{iu} - x_{ju}|^2} \]

    • 曼哈顿距离
      \(p\) 取1时,闵可夫斯基距离即为曼哈顿距离

    \[\text{dist}_{\text{man}}(\mathbf x_i, \mathbf x_j) = ||\mathbf x_i - \mathbf x_j||_1 = \sum_{u = 1}^{d}|x_{iu} - x_{ju}| \]


2. KMeans算法过程

\(\text{K-Means}\) 算法就是求解最优化问题:

\[\mathcal{C} = \text{arg}\; \min_{C} E(C) = \text{arg}\; \min_{C} \sum_{i=1}^k\sum_{x \in C_i}||x - \mu_i||^2 \]

相似的样本被聚集到同一类别后,使得损失函数 \(E\) 最小。

具体迭代方法如下:



一般情况下,为了避免运行时间过长,会设置一个最大迭代轮数或者最小调整幅度阈值,当超过最大轮数或者小于最小阈值时,退出循环。


3. KMeans 代码

from sklearn import datasets
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score

df = datasets.load_iris()
X, y = df['data'], df['target']
X = MinMaxScaler().fit_transform(X)

# 设定初始质心 KMeans是无监督学习 为了让结果和target进行比较 人工设置初始质心
init = np.array([X[y==0].mean(axis=0), X[y==1].mean(axis=0), X[y==2].mean(axis=0)])
print("初始质心: \n", init, end="\n\n")

# 分成三类
model = KMeans(n_clusters=3, n_init=init)

# 模型训练
model.fit(X)

# 输出迭代之后的质心
centroid = model.cluster_centers_
print("经过迭代之后质心为: \n", centroid, end="\n\n")

# 测试集 测试结果显示
y_pred = model.predict(X)

# 模型准确率测试
accuracy = accuracy_score(y, y_pred)
print("测试准确率为: ", accuracy, end="\n\n")
posted @ 2023-11-05 23:44  MarisaMagic  阅读(98)  评论(0编辑  收藏  举报