# 9 无监督学习

无监督学习是处理你的数据集没有标签的问题，这个特性使其成为许多实际应用的难题。对于你的模型，没有表示行为的标签意味着缺少了一个可靠的参考点来判断你的模型的质量。在这本书中，我只提出无监督学习的方法，建立根据数据而不是人类判断的可评估的模型。

##  9.1 密度估计

密度估计是对未知概率分布的数据集的概率密度函数（pdf）建模的问题。它对很多应用都是有用的，特别是在新颖或入侵检测。在第7章，我们已经估计pdf来解决一级分类问题。为此，我们决定我们的模型是参数化的，更准确的说是多元正态分布（MVN）。这个决定有些时候有点武断，因为如果我们的数据集的真实分布与MVN是不同的，我们的模型将很有可能不是很好。我们也知道模型可以是非参数的。我们在核回归中使用了非参数的模型。事实证明，相同的方法也可以用于密度估计。

令$\{x_i\}_{i=1}^N$是一维数据集（多维的情况类似），其例子来自未知概率密度函数（pdf）$f$的分布，对所有的$i=1,...,N$有$x_i\in R$。我们感兴趣的是对这个函数$f$的形式进行建模。我们的核模型$f$，让我们记它为$\hat f$，由下式给出，
$$
\hat f_b(x)=\frac {1}{Nb}\sum_{i=1}^Nk(\frac {x-x_i}{b}),
$$
$b$是超参数控制我们模型的方差和偏差之间的权衡，$k$是一个核函数。再次的，像第7章，我们使用高斯核函数
$$
k(z)=\frac {1}{\sqrt{2\pi}}exp(\frac {-z^2}{2})
$$
我们寻找一个$b$的值来最小化实际的$f$的形式和我们模型$\hat f_b$的形式之间的差异。一种合理衡量这种差异的方法被称为平均积分平方误差：
$$
MISE(b)=E[\int_R(\hat f_b(x)-f(x))^2dx]
$$
直观地，你可以看到在等式2中我们平方了实际的概率密度函数$f$和我们模型中的$\hat f$之差。积分$\int_R$代替了我们的求和$\sum_{i=1}^N$我们采用了平均误差，利用期望$E$代替了平均值$\frac 1 N$。

![Figure1](F:\翻译\Figure1.PNG)

图像1：核密度估计：$(a)$很好的拟合；$(b)$过拟合；$(c)$欠拟合；$(d)$网格曲线搜索b的最佳值。

的确，当我们的损失函数是连续域的函数时，例如$(\hat f_b(x)-f(x))^2$，我们必须要用积分来代替求和。期望$E$意味着我们希望$b$对于我们的训练集$\{x_i\}_{i=1}^{N}$所有可能的情况都是最优的。这很重要，因为$\hat f$被定义成有限样本上的某个概率分布，然而真正的概率密度函数$f$是在无限域上定义的（集合$R$）。

现在，我们可以重写等式2右边的式子，如下所示：
$$
E[\int_R{\hat f_{b}^{2}}(x)dx]-2E[\int_R{\hat f_b(x)f(x)dx}]+E[\int_R{f(x)^2dx}]
$$
上式求和的第三项和b无关，因此可以忽略。第一项的无偏差估计由$\int_R{\hat f_{b}^{2}(x)dx}$而第二项的无偏差估计可以近似为$-\frac {2}{N}\sum_{i=1}^{N}\hat f_b^{(i)}(x_i)$，其中$\hat f_{b}^{(i)}$是在我们的排除示例$x_i$的训练集上计算$f$的核模型。

式子$\sum_{i=1}^{N}$在统计学中被称为留一估计，交叉验证的一种形式，其中每折由一个例子组成。你可能已经注意到了式子$\int_R {\hat f_b(x)f(x)dx}$（让我们称它为$a$）是函数$\hat f_b$的期望值，因为函数$f$是概率密度函数。可以证明留一估计是$Ea$的无偏差估计。

现在，为了寻找$b$的最优值$b^*$，我们希望最小化如下定义的成本函数：
$$
\int_R{\hat f_{b}^{2}(x)dx}-\frac {2}{N}\sum_{i=1}^N{\hat f_{b}^{(i)}(x_i)}
$$
我们可以通过网格搜索找到$b^*$。对于$D$维特征向量$x$，等式1中的误差项$x-x_i$可以用欧几里得距离$||x-x_i||$。在图像1中，您可以看到从包含100个示例的数据集中使用3个不同的$b$值获得相同的概率密度函数的估计值，以及网格搜索曲线。我们在网格搜索曲线的最小值位置选择$b^*$。

## 9.2 聚类

聚类是通过学习未标记的数据集为示例分配标签的问题。因为数据集是完全没有被标记的，决定学习模型是否是最佳的要比监督学习中要复杂的多。

有各种各样的聚类算法，不幸的是，很难告诉你哪个算法针对你的数据集会更好一些。通常，每种算法的性能取决于数据集的概率分布的未知的属性。

### 9.2.1 K-Means

K-Means聚类算法的工作原理如下。首先，分析选择k—类（或簇）的数量。然后，我们在特征空间中随机的选取k个特征向量（称为质心）。然后我们使用一些度量去计算每个样本$x$到质心$c$之间的距离，像欧几里得距离。然后我们为每个例子分配最近的质心（就像我们用质心ID作为标签做标记每个样本）。对于每个质心，我们计算被它标记的样本的平均特征向量。这些平均的特征向量将成为质心新的位置。

![Figure2](F:\翻译\Figure2.PNG)

图2：K-Means算法过程中取了$k=3$。圆形是二维特征向量，方形表示正在移动的质心。

我们重新计算每个例子到每个质心之间的距离，修改每个样本分配的类，并重复该过程，直到重新计算质心位置后样本分配的类保持不变。模型就是给样本分配质心ID的清单。

质心的初始位置影响最终位置，因此运行两次K-Means算法可以产生两种不同的模型。K-Means算法运行一次的结果如图2所示。不同的背景颜色表示所有点属于同一簇区域。

k的值（簇的数量）是一个必须由数据分析调整的超参数。有一些选择k的技巧。它们都没有被证明是最优的。他们中的大多数要求分析通过查看某些指标或通过检查群集分配来进行“有根据的猜测”。在本章的最后，我们介绍一种技术，它允许在不查看数据和猜测的情况下为k选择合理的值。

### 9.2.2 DBSCAN和HDBSCAN

虽然K-Means和类似的算法都是基于质心的，DBSCAN是一种基于密度的聚类算法。通过使用DBSCAN，你不需要猜测类的数量，你定义两个超参数：$\epsilon$和$n$。首先，你从你的数据集中随机的选择一个样本$x$并给他标记为类1。然后你计算有多少个样本和$x$之间的距离小于或等于$\epsilon$。如果此数量大于或等于$n$，那么将所有的这些$\epsilon$近邻都放到类1中。然后检查类1中的每个成员并找到他们各自的$\epsilon$近邻。如果类1中的某个成员有$n$个或$n$多个$\epsilon$近邻，你需要在类中放入这些$\epsilon$近邻以此来扩展类。你继续扩展类1，直到没有更多示例放入其中了。其后，你从数据集中选择另一个不属于任何类的样本，并将其放入类2中。你重复上述步骤，直到所有样本都属于某个类或被标记为异常值。异常值是一个样本的$\epsilon$近邻数量小于$n$。

DBSCAN的优势在于它可以构建具有任意形状的类，而K-Means和其他的质心算法会构建具有超球面形状的类。DBSCAN的一个明显的缺点是它具有两个超参数，选择好的值（特别是$\epsilon$）可能是一项挑战。此外，在$\epsilon$固定下，聚类算法不能有效的处理不同密度的类。

HDBSCAN是保持了DBSCAN优点的聚类算法，通过消除决定$\epsilon$值的需要。该算法能构建不同密度的类。HDBSCAN是多个想法的巧妙组合，完整的描述该算法会超出本书的范围。

HDBSCAN仅只有一个重要的超参数$n$，它是放入类中最小的样本数。这种超参数通过直觉选择相对简单。HDBSCAN的实现速度特别快：它可以有效地处理数百万个样本。现今，K-Means的实现要比HDBSCAN快很多，但是在许多实际任务中，后者的优点可能要超过它的缺点。建议首先在你的数据上尝试HDBSCAN。

### 9.2.3 确定类的数量

最重要的问题是你的数据集有多少个类？当特征向量是一维，二维，三维时，你可以查看数据并看特征空间中点形成的“云”。每一个云都是一个潜在的类。但是对于$D$维数据，即$D>3$时，看数据是困难的。有一种实用的方法，它是基于预测强度的概念来确定合理的类的数量。想法是将数据分为训练集和测试集，类似于我们在监督学习中所做的。当你有训练集和测试集时，$N_{tr}$，$N_{te}$的大小分别为$S_{tr}$，$S_{te}$，你修改$k$，类的数量，在数据集$S_{tr}$和$S_{te}$上运行聚类算法$C$并且获得聚类的结果$C(S_{tr},k)$和$C(S_{te},k)$。

设$A$是使用训练集建立的聚类$C(S_{tr},k)$。注意$A$的类可以由某些区域定义。如果一个样本是属于这个区域之一的，那么这个样本属于某个特定的类。例如，我们在一些数据集上运用我们的K-Means算法，如图2所示，它将特征空间划分为$k$个多边形区域。

定义$N_{te}\times N_{te}$联合成员矩阵$D[A,S_{te}]$如下：$D[A,S_{te}]^{(i,i')}=1$，当且仅当测试集的样本$x_i$和$x_{i'}$根据类$A$属于同一类。否则$D[A,S_{te}]^{(i,i')}=0$。

让我们休息一下，看看我们在这里有什么。我们使用训练集的样本构建了具有$k$个类的聚类$A$。然后我们构建了成员联合矩阵，指示测试集中的两个样本是否属于$A$中的同一类。

直觉上，如果数量$k$是合理的聚类数量，那么类$C(S_{te},k)$中属于同一类中的两个样本也很有可能属于类$C(S_{tr},k)$中的同一类。另一方面，如果$k$是不合理的（过高或过低），那么基于训练集和基于测试集得到的类可能会不一致。

![Figure3](F:\翻译\Figure3.PNG)

图3：对于$k=4$的类，（a）训练集的类，（b）测试集的类，（c）在训练的类中绘制测试集数据

这个想法如图3所示。图3a和图3b分别表示出了$C(S_{tr},4)$和$C(S_{te},4)$及其各自的类区域。图3c表示在训练数据类区域上绘制测试样本。根据从训练数据中获得的类的区域，你可以在图3c中看到橙色测试样本不再属于同一类。这将导致矩阵$D[A,S_{te}]$中有许多0，反过来说，$k=4$可能不是最优的类的数量。

更正式的说，类$k$的数量的预测强度由下式给出：

![公式](F:\翻译\公式.PNG)

其中，![公式1](F:\翻译\公式1.PNG)$A_j$是来自类$C(S_{te},k)$的第$j$个类，$|A_j|$是类$A_j$的样本数。

给定一个类$C(S_{tr},k)$，对于每一个测试类，我们计算该类中观察对的比例，这些观察对也由训练集质心分配给同一类。预测强度是$k$个测试集群中的最小值。

![Figure4](F:\翻译\Figure4.PNG)

图4：2个，3个，4个类数据的不同$k$值的预测强度。

实验表明，合理数量的类是最大的$k$，使得$ps(k)$大于0.8。你可以在图中看到，2个，3个，4个类数据不同$k$值的预测强度的例子。

对于非确定性聚类算法，例如K-Means，根据质心的初始位置可以产生不同的聚类，建议对同一个$k$执行多次聚类算法，并计算多次运行的平均预测强度$\bar{ps}(k)$。估计类的数量的另一种有效的方法是gap statistic。其他一些分析时仍然会采用的自动化方法是elbow method和average silhouette method。

### 9.2.4 其他聚类算法

DBSCAN和K-Means计算所谓的硬聚类，每个样本只能属于一种类。高斯混合模型（GMM）允许每个样本是具有不同隶属度分数的若干类的成员（顺便说一下，HDBSCAN也允许这样做）。计算GMM与基于模型的密度估计非常相似。在GMM中，我们不是只有一个多元正态分布（MND），而是有多个多元正态分布（MND）的加权和：
$$
f_X=\sum_{j=1}^{k}\phi_jf_{\mu_j},\Sigma_j
$$

$f_{\mu_j},\Sigma_j$是一个关于$j$的多元正态分布（MND），$\phi_j$是它的权重，对于所有的$j=1,...,k$，参数$\mu_j,\Sigma_j,\phi_j$使用最大期望算法（EM）来优化最大似然准则来获得。

同样，为了简单起见，让我们来看一维数据。还假设有两个类：$k=2$。在这种情况下，我们有两个高斯分布，
$$
f(x|\mu_1,\sigma_{1}^{2})=\frac {1}{\sqrt{2\pi\sigma_{1}^{2}}}e^{-\frac {{(x-\mu_1)}^2}{2\sigma_{1}^{2}}} and f(x|\mu_2,\sigma_{2}^{2})=\frac {1}{\sqrt{2\pi\sigma_{2}^{2}}}e^{-\frac {{(x-\mu_2)}^2}{2\sigma_{2}^{2}}}
$$
$f(x|\mu_1,\sigma_{1}^{2})$和$f(x|\mu_2,\sigma_{2}^{2})$是两个参数化的概率密度分布函数（pdf），用来定义$X=x$的可能性。我们使用EM算法去估计$\mu_1,\sigma_{1}^{2},\mu_2,\sigma_{2}^{2},\phi_1,\phi_2$。GMM的参数$\phi_1,\phi_2$对于密度估计任务非常有用，而对于聚类任务没有那么有用，我们将在下面看到。

EM工作如下。在最开始，我们猜测$\mu_1,\sigma_{1}^{2},\mu_2,\sigma_{2}^{2}$的初始值，并且令$\phi_1=\phi_2=\frac {1}{2}$（通常上，对于每个$\phi_k$它是$\frac 1k$）

对于EM算法的每一次迭代，执行以下四个步骤：

1.对于所有的$i=1,...,N$，使用等式3计算每个$x_i$的可能性：
$$
f(x|\mu_1,\sigma_{1}^{2}) \leftarrow \frac {1}{\sqrt{2\pi\sigma_{1}^{2}}}e^{-\frac {{(x-\mu_1)}^2}{2\sigma_{1}^{2}}} and f(x|\mu_2,\sigma_{2}^{2}) \leftarrow \frac {1}{\sqrt{2\pi\sigma_{2}^{2}}}e^{-\frac {{(x-\mu_2)}^2}{2\sigma_{2}^{2}}}
$$
2.使用贝叶斯准则，对于每一个样本$x_i$，计算样本属于类$j\in\{1,2\}$的可能性$b_{i}^{(j)}$（换句话说，该样本是从高斯$j$中提取的可能性）：
$$
b_{i}^{(j)} \leftarrow \frac {f(x_i|\mu_j,\sigma_{j}^{2})\phi_j}{f(x_i|\mu_1,\sigma_{1}^{2})\phi_1+f(x_i|\mu_2,\sigma_{2}^{2})\phi_2}
$$
参数$\phi_j$反映了具有参数$\mu_j$和$\gamma_j$的高斯分布$j$产生我们数据集的可能性。这就是为什么开始我们另$\phi_1=\phi_2=\frac {1}{2}$：我们不知道两个高斯分布中每一个的可能性，我们通过将两者的可能性设置为一半来反映我们的未知。

![Figure5](F:\翻译\Figure5.PNG)

图5：使用EM算法对两个类$(k=2)$进行高斯混合模型估计的过程。

3.计算新的$\mu_j,\sigma_{j}^{2}$的值：
$$
\mu_j \leftarrow \frac {\sum_{i}^{N}b_{i}^{(j)}x_i}{\sum_{i}^{N}b_{i}^{(j)}} and \sigma_{j}^{2} \leftarrow \frac {\sum_{i}^{N}b_{i}^{(j)}(x_i-\mu_j)^2}{\sum_{i}^{N}b_{i}^{(j)}}
$$
4.更新$\phi_j$，$j \in \{1,2\}$
$$
\phi_j \leftarrow \frac 1N\sum_{i=1}^{N}b_{i}^{(j)}
$$
迭代执行步骤1-4直到$\mu_j,\sigma_{j}^{2}$的值不在改变很多：例如，值的变化应该低于阈值$\varepsilon$。图5说明了这个过程。

你可能注意到了EM算法和K-Means算法很相似：随机类起始，然后通过平均分配给类的数据来迭代更新类的参数。GMM情况的唯一区别在于，向类$j$分配样本$x_i$是软的：$x_i$属于类$j$的概率为$b_{i}^{(j)}$。这就是为什么我们计算等式4中$\mu_j$和$\sigma_{j}^{2}$新值不是平均值（使用K-Means）而是作为权重$b_{i}^{(j)}$的加权平均值。

一旦我们学习了每个类$j$的参数$\mu_j$和$\sigma_{j}^{2}$，类$j$中的样本$x$的得分将由$f(x|\mu_j,\sigma_{j}^{2})$给出。

扩展到D维数据（$D>1$）就很简单了。唯一的区别是，我们现在有了协方差矩阵$\Sigma$来参数化我们的多元正态分布（MND），而不是方差$\sigma^2$。GMM优于K-Means的优点在于GMM中的簇可以具有椭圆形状，其可以具有任意伸长和旋转。协方差矩阵中的值控制这些属性。

如何选择GMM中的$k$，不幸的是，没有普遍认可的方法，通常建议将数据集拆分为训练集和测试集。然后尝试不同的$k$并且为训练集上的每个$k$建立不同的模型$f_{tr}^{k}$。然后选择最大化测试集中样本可能性的模型：

![公式2](F:\翻译\公式2.PNG)

$N_{te}$是测试集的大小。

文献中描述了各种聚类算法。值得一提的是谱聚类和层次聚类。对于某些数据集，你有可能会发现更合适的模型。但是，在大多数的实际情况中，K-Means，HDBSCAN和高斯混合模型将满足您的需求。

## 9.3 降维

许多现代机器学习算法，例如集成算法和神经网络，需要处理非常高维的样本，高达数百万个特征。使用现代计算机和图形处理单元（GPU），在实践中使用降维技术比过去少的多。降维最常见的用例是数据可视化：人们最多只能在图上解释3维。

另一种从维度减少中受益的情况是，当你必须构建一个可解释的模型的时，你必须选择学习算法。例如，你只能选择决策树或线性回归。通过将数据减少到较低的维度，并通过确定缩小的要素空间中的每个新要素反映的原始示例的质量，可以使用更简单的算法。降维消除了冗余或高度相关的特征；它还可以降低数据中的噪音——所有这些都有助于模型的可解释性。

三种最广泛使用的降维技术是主成分分析（PCA），均匀流行近似和投影（UMAP）以及自动编码器。

我已经在第7章中解释了自动编码器。您可以使用自动编码器瓶颈层的低维输出表示高维输入特征向量的降维度向量。您知道这个低维向量表示输入向量中包含的基本信息，因为自动编码器能够仅基于瓶颈层输出重建输入特征向量。

### 9.3.1 主成分分析

主成分分析或PCA是最古老的方法之一。它背后的数学涉及到矩阵的操作，我在第2章没有解释，因此我将PCA的数学留给你进一步阅读。在这里，我只提供直觉并在一个例子中说明方法。

![Figure6](F:\翻译\Figure6.PNG)

图6：PCA：（a）原始数据；（b）两个主要组成部分显示为向量；（c）投影在第一主成分上的数据。

考虑二维数据，如图6a所示。主成分是定义新坐标系的向量；其中第一轴是数据集上最高的方差的方向。第二轴与第一轴正交，并沿数据中第二高方差的方向。如果我们的数据是三维的，那么第三轴将与第一个和第二个轴正交，并沿着数据中第三高方差的方向，以此类推。在图6b中，两个主要成分显示为箭头。箭头的长度反映了这个方向上的差异。

现在，如果我们想把数据的维数减少到$D_{new}<D$，我们选择$D_{new}$个最大的主成分，并且把它们投影到我们的数据集上。对于我们的二维示例，我们可以置$D_{new=1}$并将我们的示例投影到第一个主要成分上，以获得图6c上的橙色点。

为了描述每个橙色点，我们只需要一个坐标而不是两个，第一个主成分的坐标。当我们的数据是高维时，在实践中经常会发生前两个或三个主要成分占了数据的大部分变化，因此通过在二维或三维绘图上显示数据，我们可以看到高维度数据及其属性。

### 9.3.2 UMAP

许多现代降维算法背后的思想，特别是那些专门为可视化目的而设计的算法，如t-SNE和UMAP，基本上是相同的。我们首先为两个例子设计一个相似性度量。为了可视化的目的，除了两个例子之间的欧几里得距离之外，这个相似性度量经常反映两个例子的一些局部特性，例如它们周围其他例子的密度。

在UMAP中，这种相似性的度量$\omega$定义如下，

![公式5](F:\翻译\公式5.PNG)

函数$w_i(x_i,x_j)$定义如下，

![公式6](F:\翻译\公式6.PNG)

其中$d(x_i,x_j)$是两个样本之间的欧几里得距离，$\rho_i$是$x_i$到最近邻居的距离，并且$\sigma_i$是$x_i$到第$k$个最近邻居的距离（$k$是算法的超参数）。

可以看出等式5中的变量在0到1的范围内变化并且是对称的，这意味着$w(x_i,x_j)=w(x_j,x_i)$。

设$\omega$表示原始高维空间中两个样本的相似性，并且$\omega'$是新的低维空间中由相同的等式5给出的相似度。因为$\omega$和$\omega'$的值介于0到1之间，我们可以将它们视为两个概率分布。两种概率分布之间广泛使用的相似度量是交叉熵：
$$
C(w,w')=\sum_{i=1}^{N}\sum_{j=1}^{N}w(x_i,x_j)ln(\frac {w(x_i,x_j)}{w'(x'_i,x'_j)})+(1-w(x_i,x_j))ln(\frac {1-w(x_i,x_j)}{1-w'(x'_i,x'_j)})
$$
其中，$x'$是原始高维样本$x$的低维版本。

正如你从等式6中看到的那样，当$w(x_i,x_j)$类似于$w'(x'_i,x'_j)$时，对于所有的对$(i,j)$，$C(w,w')$是最小化的。这正是我们想要的：对于任意两个样本$x_i$和$x_j$，我们希望它们在原始空间和低维空间中的相似性度量尽可能相似。

在等式6中，我们未知的参数是$x'$（$i=1,2,...,N$），我们可以利用梯度下降最小化$C(w,w')$来计算得出。

![Figure7](F:\翻译\Figure7.PNG)

图7：使用3种不同的技术降低MNIST数据集的维数。

在图7中，您可以看到应用于手写数字的MNIST数据集的降维结果。MNIST通常用于对各种图像处理系统进行基准测试；它包含70000个标签样本。图中的10个不同的颜色对应10个类。图中的每个点对应于数据集中特定样本。正如你所看到的，UMAP在视觉上更好的分离了样本（记住，它无法访问标签）。实际上，UMAP略慢于PCA，但比自动编码器快。

## 9.4 异常值检测

异常值检测是在数据集中检测与数据集中的典型样本非常不同的样本的问题。我们已经看到了几种可以帮助解决这个问题的技术：自动编码器和一类分类器学习。如果，我们使用了自动编码器，我们会在训练集上训练它。然后，如果我们想要预测样本是否是异常值，我们可以使用自动编码器从瓶颈层重建样本。该模型不太可能重建异常值。

在一类分类问题中，模型要么预测输入样本属于该类，要么预测它是一个异常值。