【第8周:聚类和降维】


前几周,我们已经接触到了许多监督学习算法:线性回归,逻辑回归,支持向量机,此外神经网络也可用于处理监督学习的问题。本周将开始学习无监督学习算法:聚类算法和降维算法。

聚类

聚类的目标是将一系列无标签的训练数据,输入到算法中,找到数据的内在结构。比如将下图的两簇数据分别圈出来的算法,就是一个聚类算法。
在这里插入图片描述
聚类的应用:
市场分割:对客户信息分类分别制定商业计划
相册分类:根据人脸相似度自动分类

K-均值迭代算法

K-均值是最常见的聚类算法,可以将数据聚类成不同的组。
代价函数和目标函数:
在这里插入图片描述
在这里插入图片描述
c1,c2,……,cm 来存储与第m个样本最近的聚类中心的索引值
𝜇1,𝜇2,……,𝜇𝑘 表示聚类中心

步骤

  1. 随机初始化所有的聚类中心点𝜇𝑘
    条件:令这k个聚类中心为随机的k个样本。(k<m)
    可能存在局部最优问题,需要多次运行 K-均值找代价函数最小的结果,但是当k很大时,多次运行可能没什么差别。
  2. 类别标定
    找到 离 第m个样本 最近的 聚类中心k,并将该聚类中心的索引值存储在cm中。
  3. 移动聚类中心
    对有相同索引值的样本进行平均计算找到一个质心作为新的聚类中心
  4. 重复2,3步骤直到聚类中心不变

聚类中心数k的选择

肘部法则:
在这里插入图片描述
y轴是代价函数计算出的误差,x轴是聚类中心数。当得到左边的曲线,选择“肘部”的聚类数比较合理;但当得到右边曲线时,往往需要从后续的工作要求等角度来思考。

降维

目的:
数据压缩:将冗余的数据从高维降至低维,可以加快算法速度。
数据可视化:特征太多时,往往不能够可视化,降低到一二三维就可以显示出来。

主成分分析法(PCA)

主成分分析法是最常见的降维算法。在 PCA 中,我们要做的是找到一个方向向量,当我们把所有的数据都投射到该向量上时,我们希望投射平均均方误差能尽可能地小。方向向量是一个经过原点的向量,而投射误差是从特征向量向该方向向量作垂线的长度(如右图)。投射误差最小保证了数据的特性损失最小。在这里插入图片描述

步骤

  1. 均值归一化(特征缩放)
    计算出所有特征的均值𝜇𝑗,然后令 𝑥𝑗 = 𝑥𝑗 − 𝜇𝑗。如果特征是在不同的数量级上,我们还需要将其除以方差σ²
  2. 计算协方差矩阵Covariance Matrix
    在这里插入图片描述
  3. 利用奇异值分解来计算协方差矩阵𝛴的特征向量
    奇异值分解在MATLAB的工具函数为: [U, S, V]= svd(𝛴)
    解出后,U是一个与数据之间具有最小投射误差的方向向量构成的矩阵。要将数据降至𝑘维,我们只需要从U中选取前𝑘列向量,获得一个𝑛 × 𝑘维度的矩阵,我们用𝑈𝑟𝑒𝑑𝑢𝑐𝑒表示。
  4. 计算k维的新特征向量z
    在这里插入图片描述

选择主成分k的数量

我们希望在投射的平均均方误差训练集方差的比例尽可能小的情况下选择尽可能小的𝑘值。
投射的平均均方误差与训练集方差的比例:
在这里插入图片描述
如果我们希望这个比例小于1%,就意味着原本数据的偏差有 99%都保留下来了。
方法1:
先令𝑘 = 1,运行PCA,获得𝑈𝑟𝑒𝑑𝑢𝑐𝑒和𝑧,然后计算该比例是否小于1%。不满足条件再令𝑘=2,如此类推,直到找到可以使得比例小于 1%的最小𝑘值。
方法2:
奇异值分解中, [U, S, V] = svd(𝛴)。其中S是由特征值组成的对角矩阵,可以使用矩阵S来计算投射的平均均方误差与训练集方差的比例:在这里插入图片描述

重建原始数据

在压缩过数据后,我们可以采用如下方法来近似地获得原有的特征:
在这里插入图片描述

PCA应用常见的错误

  1. PCA可以通过降维减少特征数来解决过拟合问题吗?
    答:这样做非常不好,不如尝试正则化处理。
    原因在于主要成分分析只是近似地丢弃掉一些特征,它不考虑与结果有关的特征变量,因此可能会丢失非常重要的特征。然而当我们进行正则化处理时,会考虑到结果变量,不会丢掉重要的数据。
  2. 默认地将PCA作为学习过程中的一部分
    最好还是从所有原始特征开始,只在有必要的时候(算法运行太慢或者占用太多内存)才考虑采用主要成分分析。
  • 33
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
步骤 3.6:读入 PCA 降维后的二维鸢尾花数据集 假设已经完成了 PCA 降维处理,生成了二维的数据集,可以使用 numpy 库中的 loadtxt 函数读取数据集文件,例如: ```python import numpy as np data = np.loadtxt('pca_iris_data.txt') ``` 这里假设数据集文件名为 pca_iris_data.txt,读取后得到的 data 是一个二维的 numpy 数组,其中每行代表一个样本,每列代表一个特征。 步骤 3.7:按 Kmeans 算法描述的过程完成数据集的聚类处理(取 K=2) 可以按照以下步骤实现 Kmeans 算法: 1. 随机选择 K 个样本作为初始聚类中心向量。 2. 对于每个样本,计算其到每个聚类中心向量的距离,并将其分配到距离最近的聚类中心的簇中。 3. 对于每个簇,重新计算其聚类中心向量。 4. 重复步骤 2 和 3,直到聚类中心向量不再发生变化或达到最大迭代次数。 具体实现可以参考以下代码: ```python import numpy as np def kmeans(data, k, max_iter=100): # 随机选择 k 个样本作为初始聚类中心向量 centers = data[np.random.choice(data.shape[0], size=k, replace=False), :] for i in range(max_iter): # 分配每个样本到距离最近的聚类中心的簇中 distances = np.sqrt(((data - centers[:, np.newaxis])**2).sum(axis=2)) clusters = np.argmin(distances, axis=0) # 重新计算每个簇的聚类中心向量 for j in range(k): centers[j] = data[clusters == j].mean(axis=0) return clusters, centers ``` 在调用 kmeans 函数进行聚类时,需要传入数据集和聚类数 k,例如: ```python clusters, centers = kmeans(data, k=2) ``` 聚类结果会返回每个样本所属的簇编号 clusters 和每个簇的聚类中心向量 centers。 步骤 3.8:调用 matplotlib 的 scatter 函数将聚类后各样本以及聚类中心的可视化输出 可以使用 matplotlib 库中的 scatter 函数将聚类后的数据可视化输出,不同簇内的样本可以用不同的颜色表示,例如: ```python import matplotlib.pyplot as plt colors = ['red', 'blue'] for i in range(2): plt.scatter(data[clusters==i, 0], data[clusters==i, 1], c=colors[i], label='Cluster {}'.format(i+1)) plt.scatter(centers[:, 0], centers[:, 1], c='black', marker='x', s=200, label='Centers') plt.legend() plt.show() ``` 这里假设聚类数为 2,颜色列表为 ['red', 'blue'],聚类中心用黑色的 X 标记表示。 步骤 3.9:调用 sklearn 库中的 rand_score、fowlkes_mallows_score、davies_bouldin_score 函数,计算得到外部指标(RI、FMI)和内部指标(DBI),并与调库的结果进行对比分析,是否相同,如有不同其可能原因。 可以使用 sklearn 库中的 rand_score、fowlkes_mallows_score 和 davies_bouldin_score 函数来计算聚类的外部指标和内部指标,例如: ```python from sklearn.metrics import rand_score, fowlkes_mallows_score, davies_bouldin_score # 计算外部指标 rand_index = rand_score(iris_target, clusters) fmi = fowlkes_mallows_score(iris_target, clusters) # 计算内部指标 dbi = davies_bouldin_score(data, clusters) ``` 这里假设 iris_target 是真实的鸢尾花类别标签,clusters 是聚类结果,data 是二维的数据集。计算出的外部指标和内部指标可以与 sklearn 库中的结果进行对比分析,如果相同,则说明算法实现正确;如果不同,则可能是代码实现的问题,需要进行调试。 步骤 3.10:寻找最佳聚类数 K 可以采用轮廓系数(silhouette coefficient)来寻找最佳聚类数 K。轮廓系数是评估聚类质量的一种指标,其取值范围在 [-1, 1] 之间,值越大表示聚类效果越好。 具体实现可以参考以下代码: ```python from sklearn.metrics import silhouette_score silhouette_scores = [] for k in range(2, 9): clusters, _ = kmeans(data, k) score = silhouette_score(data, clusters) silhouette_scores.append(score) plt.plot(range(2, 9), silhouette_scores) plt.xlabel('Number of clusters') plt.ylabel('Silhouette score') plt.show() ``` 这里假设聚类数的取值范围为 2~8,计算出每个聚类数对应的轮廓系数,并画出折线图。可以根据折线图找到最佳聚类数 K 的取值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值