基于原型的聚类方法

文章目录

  • 一、概念
  • 二、K-Means
    • 2.1 算法流程
    • 2.2 超参数
    • 2.3 特性
    • 2.4 解析
    • 2.5 K-Means++
    • 2.6 Python实现
  • 三、K-Mediods
    • 3.1 概念
    • 3.2 算法对比
  • 四、特性

一、概念

  原型”是指样本空间中具有代表性的点。

  原型聚类假设聚类结构可以通过一组原型刻画,这一方法在实际聚类任务中最为常用,理解起来也较简单;通常算法先对原型进行初始化,然后对原型进行迭代更新求解。采用不同的原型表示,不同的求解方式,即会产生不同的聚类算法。最经典的原型聚类算法即:

  • K−MeansK-MeansK−Means 聚类算法:基于各个样本点与各个聚集簇的中心点距离远近,进行划分的聚类算法。
  • K−MediodsK-MediodsK−Mediods 算法:在 K−MeansK-MeansK−Means 基础上改进的算法。

二、K-Means

2.1 算法流程

  算法思想

  • 输入聚类个数 kkk ,以及包含 nnn 个数据对象的数据集,输出标准的 kkk 个聚类的一种算法。
  • 然后将 nnn 个数据对象划分为 kkk 个聚类,而最终所获得的聚类满足:
    • 同一聚类中的对象相似度较高;
    • 而不同聚类中的对象相似度较小。

  KKK 均值聚类的核心目标是将给定的数据集划分成 KKK 个簇,并给出每个数据对应的簇中心点。算法的具体步骤描述如下:

  1. 数据预处理,如归一化、离群点处理等;

  2. 随机选取 KKK 个簇中心,记为 μ10,μ20,…,μK0\mu_1^0,\mu_2^0,\dots,\mu_K^0μ10​,μ20​,…,μK0​ ;

  3. 定义代价函数:J(c,μ)=min⁡μmin⁡c∑i=1M∥xi−μci∥J(c, \mu) = \min\limits_\mu \min\limits_c \sum \limits ^M_{i=1}\|x_i - \mu_{ci}\|J(c,μ)=μmin​cmin​i=1∑M​∥xi​−μci​∥;

  4. 令 t=0,1,2,…t = 0,1,2,\dotst=0,1,2,… 为迭代步数,重复下面过程直到 JJJ 收敛:

    • 对于每一个样本 xix_ixi​,将其分配到距离最近的簇
      cit←argmin⁡k∥xi−μkt∥2c_i^t \leftarrow \operatorname{argmin}_{k} \|x_i-\mu_k^t\|^2 cit​←argmink​∥xi​−μkt​∥2

    • 对于每一个类簇 kkk,重新计算该类簇的中心
      μkt+1←argmin⁡μ∑i:cit=k∥xi−μ∥2\mu_k^{t+1} \leftarrow \operatorname{argmin}_\mu \sum\limits_{i:c_i^t = k} \|x_i - \mu\|^2 μkt+1​←argminμ​i:cit​=k∑​∥xi​−μ∥2

  KKK 均值算法在迭代时,假设当前 JJJ 没有达到最小值,那么首先固定簇中心 {μk}\{\mu_k\}{μk​},调整每个样例 xix_ixi​ 所属的类别 cic_ici​ 来让 JJJ 函数减少;然后固定 {ci}\{c_i\}{ci​},调整簇中心 {μk}\{\mu_k\}{μk​} 使 JJJ 减少,这两个过程交替循环,JJJ 单调递减;当 JJJ 递减到最小值时,{μk}\{\mu_k\}{μk​} 和 {cj}\{c_j\}{cj​} 也同时收敛。

  物理意义来说:质心就是质量中心,重心就是重力受力的集合点,形心就是几何形状的中心。质心一般和重心位置相同,看受重力情况来确定,形心则是一般为规则图形,如果不规则,一般算不了。他们的区别:当质量均匀,形状规则的物体,三个都在一点,若质量不均匀,那么形心和那两个是分开的。

2.2 超参数

  K−MeansK-MeansK−Means 算法首先选择 KKK 个初始质心,其中 KKK 是用户指定的参数,即所期望的簇的个数。这样做的前提是已经知道数据集中包含多少个簇,但很多情况下,我们并不知道数据的分布情况。如何有效地确定KKK 值,提供以下几种方法:

  • 从实际问题出发,人工指定比较合理的K值,通过多次随机初始化聚类中心选取比较满意的结果
  • 均方根:假设我们有 mmm 个样本,该方法认为 K=m/2K=\sqrt{m/2}K=m/2​
  • 枚举法:用不同的 KKK 值进行聚类
    • 分别计算类内距离均值和类间距离均值之比,选择最小的那个KKK 值
    • 对不同 KKK 值都产生 222 次聚类,选择两次聚类结果最相似的 KKK 值
  • 手肘法(ElbowElbowElbow)、层次聚类法等

  用户指定的参数也称为超参数,该类参数无法通过模型对数据训练获得。

  核心指标:SSE(sumofthesquarederrorsSSE(sum \; of \; the \; squared \; errorsSSE(sumofthesquarederrors,误差平方和) SSESSESSE 是所有样本的聚类误差,代表了聚类效果的好坏。

  手肘法:随着聚类数 kkk 的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和 SSESSESSE 自然会逐渐变小。当k小于真实聚类数时,由于 kkk 的增大会大幅增加每个簇的聚合程度,故 SSESSESSE 的下降幅度会很大,而当 kkk 到达真实聚类数时,再增加 kkk 所得到的聚合程度回报会迅速变小,所以 SSESSESSE 的下降幅度会骤减,然后随着 kkk 值的继续增大而趋于平缓,也就是说 SSESSESSE 和 kkk 的关系图是一个手肘的形状,而这个肘部对应的 kkk 值就是数据的真实聚类数。

2.3 特性

  优点

  • 简单、易于理解、运算速度快;
  • 对处理大数据集,该算法保持可伸缩性和高效性;
  • 当簇接近高斯分布时,它的效果较好。

  缺点

  • 在 K−MeansK-MeansK−Means 算法是局部最优的,容易受到初始质心的影响;
  • 在 K−MeansK-MeansK−Means 算法中 KKK 值需要事先给定的,有时候 KKK 值的选定非常难以估计;
  • 在簇的平均值可被定义的情况下才能使用,只能应用连续型数据;
  • 该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的性能(时间和计算资源)开销是非常大的;
  • 对噪声和孤立点数据敏感。

欧几里德距离是数学加减乘除算出来的距离,因此这就是只能用于连续型变量的原因。

2.4 解析

  • 初始簇心的选择

    • 有时候会影响最终的聚类结果,实际操作中,我们一般会选用不同的数据作为初始簇心,多次执行K−MeansK-MeansK−Means 算法;
    • 新质心不一定是实际的一个数据点。
  • K−MeansK-MeansK−Means 算法超参数 KKK
    • KKK 是用户指定的参数,即所期望的簇的个数。KKK 指定的前提是已知数据集中包含多少个簇,但很多情况下,并不知道数据的分布情况,需要凭借业务专家的经验;
    • 常见做法是多尝试几个 KKK 值,看分成几类的结果更好解释,更符合分析目的等;或者可以把各种 KKK 值算出的 SSESSESSE 做比较,取最小的 SSESSESSE 的 KKK 值。
  • K−MeansK-MeansK−Means 算法会不会陷入一直选质心的过程,永远停不下来?
    • 不会。数学证明一定会收敛,目标函数 SSESSESSE 是可收敛的函数,但数据量大时,收敛时间可能较长。

  业务专家的作用非常大,主要体现在聚类变量的选择和对于聚类结果的解读:

  比如要对于现有的客户分群,那么就要根据最终分群的目的选择不同的变量来分群,这就需要业务专家经验支持。如果要优化客户服务的渠道,那么就应选择与渠道相关的数据;如果要推广一个新产品,那就应该选用用户目前的使用行为的数据来归类用户的兴趣。算法是无法做到这一点的

  欠缺经验的分析人员和经验丰富的分析人员对于结果的解读会有很大差异。其实不光是聚类分析,所有的分析都不能仅仅依赖统计学家或者数据工程师。

  最小化 SSESSESSE 目标函数 误差平方和函数(原本含义是拟合数据和原始数据对应点的误差的平方和)

2.5 K-Means++

  K−MeansK-MeansK−Means 与 K−Means++K-Means++K−Means++:

  不同于 K−MeansK-MeansK−Means 算法第一次是随机选择 KKK 个聚类中心,K−Means++K-Means++K−Means++ 是假设已经选取了 ppp 个初始聚类中心 (0<p<K)(0<p<K)(0<p<K),则在选取第 p+1p+1p+1 个聚类中心时:距离当前 ppp 个聚类中心越远的点会有更高的概率被选为第 p+1p+1p+1 个聚类中心。只有在选取第一个聚类中心 (p=1)(p=1)(p=1) 时是通过随机的方法。该改进方法符合一般的直觉:聚类中心互相之间距离得越远越好。这个改进直观简单,也非常有效。
其他改进算法还有:

  • ISODATAISODATAISODATA:对于高纬度的数据样本,针对KKK值事先不一定能准确指定的情况,当属于某个类别的样本数过少时把这个类别去除,当属于某个类别的样本数过多、分散程度较大时把这个类别分为两个子类别。

  KMeans++KMeans++KMeans++ 也是解决解决 KMeansKMeansKMeans 的初值敏感的问题,它与二分 K−MeansK-MeansK−Means 不同的是:在选择两个聚类点的时候不是随机选择,而是先随机选择一个点,第二个选择距离该点最远的点,再进行划分。当然,为了避免异常点的存在,第二个点的选择会选择距离较远的几个点并进行加权选择最终的第二个点。

  K−MeansK-MeansK−Means :随机的选取初始质心,但是这样簇的质量常常很差。处理选取初始质心问题的一种常用技术是:多次运行,每次使用一组不同的随机初始质心,然后选取具有最小 SSESSESSE(误差的平方和)的簇集。

  KMeans++KMeans++KMeans++:随机地选择第一个点,或取所有点的质心作为第一个点。然后,对于每个后继初始质心,选择离已经选取过的初始质心最远的点。使用这种方法,确保了选择的初始质心不仅是随机的,而且是散开的。但是,这种方法可能选中离群点。此外,求离当前初始质心集最远的点开销也非常大。为了克服这个问题,通常该方法可以用于抽样和筛出离群点后的样本数据上。

2.6 Python实现

import timeimport numpy as np
import matplotlib.pyplot as pltfrom sklearn.cluster import MiniBatchKMeans, KMeans
from sklearn.metrics.pairwise import pairwise_distances_argmin
from sklearn.datasets import make_blobsnp.random.seed(42)batch_size = 45
centers = [[1, 1], [-1, -1], [1, -1]]
n_clusters = len(centers)
X, labels_true = make_blobs(n_samples=3000, centers=centers, cluster_std=0.7)k_means = KMeans(init="k-means++", n_clusters=3, n_init=10)
t0 = time.time()
k_means.fit(X)
t_batch = time.time() - t0mbk = MiniBatchKMeans(init="k-means++",n_clusters=3,batch_size=batch_size,n_init=10,max_no_improvement=10,verbose=0,
)
t0 = time.time()
mbk.fit(X)
t_mini_batch = time.time() - t0fig = plt.figure(figsize=(8, 3))
fig.subplots_adjust(left=0.02, right=0.98, bottom=0.05, top=0.9)
colors = ["#4EACC5", "#FF9C34", "#4E9A06"]k_means_cluster_centers = k_means.cluster_centers_
order = pairwise_distances_argmin(k_means.cluster_centers_, mbk.cluster_centers_)
mbk_means_cluster_centers = mbk.cluster_centers_[order]k_means_labels = pairwise_distances_argmin(X, k_means_cluster_centers)
mbk_means_labels = pairwise_distances_argmin(X, mbk_means_cluster_centers)ax = fig.add_subplot(1, 3, 1)
for k, col in zip(range(n_clusters), colors):my_members = k_means_labels == kcluster_center = k_means_cluster_centers[k]ax.plot(X[my_members, 0], X[my_members, 1], "w", markerfacecolor=col, marker=".")ax.plot(cluster_center[0],cluster_center[1],"o",markerfacecolor=col,markeredgecolor="k",markersize=6,)ax.set_title("KMeans")
ax.set_xticks(())
ax.set_yticks(())
plt.text(-3.5, 1.8, "train time: %.2fs\ninertia: %f" % (t_batch, k_means.inertia_))ax = fig.add_subplot(1, 3, 2)
for k, col in zip(range(n_clusters), colors):my_members = mbk_means_labels == kcluster_center = mbk_means_cluster_centers[k]ax.plot(X[my_members, 0], X[my_members, 1], "w", markerfacecolor=col, marker=".")ax.plot(cluster_center[0],cluster_center[1],"o",markerfacecolor=col,markeredgecolor="k",markersize=6,)
ax.set_title("MiniBatchKMeans")
ax.set_xticks(())
ax.set_yticks(())
plt.text(-3.5, 1.8, "train time: %.2fs\ninertia: %f" % (t_mini_batch, mbk.inertia_))different = mbk_means_labels == 4
ax = fig.add_subplot(1, 3, 3)for k in range(n_clusters):different += (k_means_labels == k) != (mbk_means_labels == k)identic = np.logical_not(different)
ax.plot(X[identic, 0], X[identic, 1], "w", markerfacecolor="#bbbbbb", marker=".")
ax.plot(X[different, 0], X[different, 1], "w", markerfacecolor="m", marker=".")
ax.set_title("Difference")
ax.set_xticks(())
ax.set_yticks(())plt.show()

三、K-Mediods

3.1 概念

  K−MediodsK-MediodsK−Mediods 是基于原型的另一种聚类算法,也是对 K−MeansK-MeansK−Means 算法的一种改进。

算法描述

  1. 随机选取一组样本作为中心点集;
  2. 每个中心点对应一个簇;
  3. 计算各样本点到各个中心点的距离(如欧氏距离),将样本点放入距离中心点最短的那个簇中;
  4. 计算各簇中,距簇内各样本点距离的绝对误差最小的点,作为新的中心点;
  5. 如果新的中心点集与原中心点集相同,算法终止;如果新的中心点集与原中心点集不完全相同,返回2)。

3.2 算法对比

  K−MediodsK-MediodsK−Mediods 聚类算法原理和 K−MeansK-MeansK−Means 大体相似,算法流程基本一致,不同的是:

  • 质心的计算方式不同

    • K−MeansK-MeansK−Means 聚类算法更新聚簇中心的时候直接计算均值,以均值点作为新的中心,可能是样本点中不存在的点;而 K−MediodsK-MediodsK−Mediods更新聚簇中心是计算每一个点到簇内其他点的距离之和,选择距离和最小的点来作为新的聚簇中心,质心必须是某些样本点的值。
  • K−MediodsK-MediodsK−Mediods 可以避免数据中的异常值带来的影响。

    • 如一个二维的样本集划分的簇是 {(1,1),(1,2),(2,1),(1000,1000)}\{(1,1),(1,2),(2,1),(1000,1000)\}{(1,1),(1,2),(2,1),(1000,1000)},其中 (1000,1000)(1000,1000)(1000,1000) 是噪声点。按照 K−MeansK-MeansK−Means 算法,该样本集的质心则为 (502,502)(502,502)(502,502),但这个新的质心并不是该样本集大多数正常样本点围绕的中心;如果是选择 K−MedoidsK-MedoidsK−Medoids 就可以避免这种情况,它会在 {(1,1),(1,2),(2,1),(1000,1000)}\{(1,1),(1,2),(2,1),(1000,1000)\}{(1,1),(1,2),(2,1),(1000,1000)}中选出一个样本点使它到其他所有点的距离之和绝对误差最小,计算可知一定会在前三个点中选取。
  • K−MediodsK-MediodsK−Mediods 聚类算法原理和 K−MeansK-MeansK−Means 大体相似,算法流程基本一致,不同的是:

    • 质心的计算复杂度更高:在质心的选取上,K−MeansK-MeansK−Means 只需要计算每个划分的簇均值中心点获得新的质心,而 K−MedoidsK-MedoidsK−Medoids 需要计算每个簇任两点之间的距离,再对每个距离进行比较获取新的质心,计算复杂度增加,运行速度会较慢;

    • 稳定性更高、执行速度变慢:对于有异常值的小样本量数据集, K−MediodsK-MediodsK−Mediods 比 K−MeansK-MeansK−Means 效果更稳定,但是随着数据集规模增加,K−MediodsK-MediodsK−Mediods 算法的执行速度会慢很多;

    • 如果数据集本身不存在特别多的异常值,也不需要使用 K−MediodsK-MediodsK−Mediods 替代 K−MeansK-MeansK−Means 。

        K−MediodsK-MediodsK−Mediods 每次迭代后的质点都是从聚类的样本点中选取,而选取的标准就是当该样本点成为新的质点后能提高类簇的聚类质量,使得类簇更紧凑。该算法使用绝对误差标准来定义一个类簇的紧凑程度

四、特性

K−MeansK-MeansK−Means:


优点:

  1. 简单,易于理解,运算速度快;
  2. 对处理大数据集,该算法可保持可伸缩性和高效性;
  3. 当簇接近高斯分布时,它的效果较好;

缺点:

  1. K−MeansK-MeansK−Means 算法是局部最优的,容易受到初始质心的影响;
  2. 在 K−MeansK-MeansK−Means 算法中 KKK 值是需要事先给定的,有时候 KKK 值非常难以估计;
  3. 在簇的平均值可被定义的情况下才能使用,只能应用连续型数据;
  4. 大数据情况下算法的开销是非常大的;
  5. 对噪声和孤立点数据敏感。

K−MediosK-MediosK−Medios:


优点:

  1. K−MediosK-MediosK−Medios 算法具有处理大数据集的能力
  2. 结果簇相当紧凑,并且簇与簇之间明显分明;
  3. 相比于 K−MeansK-MeansK−Means 对噪声点不敏感;

缺点:

  1. 只适用于连续型数据;
  2. 只适用于聚类结果为凸性的数据集等;
  3. 必须事先确定 KKK 值;
  4. 一般在一个局部最优的解后就停止了。

区别:

  1. 与K−MeansK-MeansK−Means 相比,K−MediosK-MediosK−Medios 算法对于噪声不那么敏感,这样对于离群点就不会造成划分的结果偏差过大,少数数据不会造成重大影响;
  2. K−MediosK-MediosK−Medios 由于上述原因被认为是对 K−MeansK-MeansK−Means 改进,但由于中心点的选择的方式进行计算,算法的时间复杂度也比 K−MeansK-MeansK−Means 上升了 O(n)O(n)O(n)。

. 相比于 K−MeansK-MeansK−Means 对噪声点不敏感;

缺点:

  1. 只适用于连续型数据;
  2. 只适用于聚类结果为凸性的数据集等;
  3. 必须事先确定 KKK 值;
  4. 一般在一个局部最优的解后就停止了。

区别:

  1. 与K−MeansK-MeansK−Means 相比,K−MediosK-MediosK−Medios 算法对于噪声不那么敏感,这样对于离群点就不会造成划分的结果偏差过大,少数数据不会造成重大影响;
  2. K−MediosK-MediosK−Medios 由于上述原因被认为是对 K−MeansK-MeansK−Means 改进,但由于中心点的选择的方式进行计算,算法的时间复杂度也比 K−MeansK-MeansK−Means 上升了 O(n)O(n)O(n)。

2.基于原型的聚类方法相关推荐

  1. 【数据挖掘】基于方格的聚类方法 ( 概念 | STING 方法 | CLIQUE 方法 )

    文章目录 I . 基于方格的聚类方法 简介 II . 基于方格的聚类方法 图示 III . STING 方法 IV . CLIQUE 方法 I . 基于方格的聚类方法 简介 1 . 基于方格的聚类方法 ...

  2. 【数据挖掘】基于层次的聚类方法 ( 聚合层次聚类 | 划分层次聚类 | 族间距离 | 最小距离 | 最大距离 | 中心距离 | 平均距离 | 基于层次聚类步骤 | 族半径 )

    文章目录 基于层次的聚类方法 简介 基于层次的聚类方法 概念 聚合层次聚类 图示 划分层次聚类 图示 基于层次的聚类方法 切割点选取 族间距离 概念 族间距离 使用到的变量 族间距离 最小距离 族间距 ...

  3. 【数据挖掘】基于密度的聚类方法 - DBSCAN 方法 ( K-Means 方法缺陷 | 基于密度聚类原理及概念 | ε-邻域 | 核心对象 | 直接密度可达 | 密度可达 | 密度连接 )

    文章目录 I . K-Means 算法在实际应用中的缺陷 II . K-Means 初始中心点选择不恰当 III . K-Means 优点 与 弊端 IV . 基于密度的聚类方法 V . 基于密度的聚 ...

  4. 【数据挖掘】基于划分的聚类方法 ( K-Means 算法简介 | K-Means 算法步骤 | K-Means 图示 )

    文章目录 一. 基于划分的聚类方法 二. K-Means 算法 简介 三. K-Means 算法 步骤 四. K-Means 方法的评分函数 五. K-Means 算法 图示 一. 基于划分的聚类方法 ...

  5. 【数据挖掘】聚类算法 简介 ( 基于划分的聚类方法 | 基于层次的聚类方法 | 基于密度的聚类方法 | 基于方格的聚类方法 | 基于模型的聚类方法 )

    文章目录 I . 聚类主要算法 II . 基于划分的聚类方法 III . 基于层次的聚类方法 IV . 聚合层次聚类 图示 V . 划分层次聚类 图示 VI . 基于层次的聚类方法 切割点选取 VII ...

  6. 机器学习 聚类篇——python实现DBSCAN(基于密度的聚类方法)

    机器学习 聚类篇--python实现DBSCAN(基于密度的聚类方法) 摘要 python实现代码 计算实例 摘要 DBSCAN(Density-Based Spatial Clustering of ...

  7. 密度聚类dbscan_DBSCAN —基于密度的聚类方法的演练

    密度聚类dbscan The idea of having newer algorithms come into the picture doesn't make the older ones 'co ...

  8. 基于密度的聚类方法-OPTICS

    在DBSCAN算法中,我们知道该算法需要用户输入半径和阀值.这显然是不靠谱的,虽然我们可以通过其他方法来优化参数的选择,但这其实不是最好的做法.  这里为了克服在聚类分析中使用一组全局参数的缺点,这里 ...

  9. 【数据挖掘】基于密度的聚类方法 - DBSCAN 方法 ( DBSCAN 原理 | DBSCAN 流程 | 可变密度问题 | 链条现象 | OPTICS 算法引入 | 聚类层次 | 族序概念 )

    文章目录 I . DBSCAN 简介 II . DBSCAN 算法流程 III . DBSCAN 算法 优缺点 IV . 可变密度问题 V . 链条现象 VI . OPTICS 算法原理 VII . ...

最新文章

  1. emmc linux.格式化参数,SD卡, EMMC固化 ,关于bootloader linux
  2. 深入理解分布式技术 - 分布式缓存实战_常见的坑及解决办法
  3. UPS故障案例集(一)
  4. 中输入learn_Scikit-learn新版本发布,一行代码秒升级
  5. 实现DDD领域驱动设计: Part 2
  6. ASP.Net 管道模型 VS Asp.Net Core 管道 总结
  7. 2.2 string
  8. html:(4):认识html文件基本结构和认识head标签
  9. 紧急救援 L2-001 dijkstra 打印路径 最短路条数 权值
  10. centos7 安装sogou输入法
  11. 盖洛普Q12测评法(转载)
  12. 乔布斯斯坦福毕业演讲,这是我听过最精彩的毕业演讲!
  13. NKOJ 2522 Sandy的卡片(差分数组+DP)
  14. Microsoft Edge 收藏夹如何显示在界面上方?
  15. NVIDIA Jetson AGX Orin的计算能力
  16. 一天上手Aurora 8B/10B IP核(4)----从Streaming接口的官方例程学起
  17. 稳压二极管与TVS二极管的区别
  18. 18、无线局域网(介质访问控制子层)
  19. MT4/MQL4入门到精通EA教程第六课-MQL语言常用函数(六)-常用订单功能函数
  20. Spring是什么,为什么要学Spring

热门文章

  1. Java调用cplex求解运输问题
  2. 最短编辑距离(动态规划超详细填表法)
  3. mysql geojson_GeoJSON
  4. 创建FTP服务器下载文件时出现`当前的安全设置不允许从该位置下载文件`
  5. html之表格table例题-个人简历
  6. 举例用Python爬取科目四考试题库的详细方法
  7. thymeleaf从后台application中取值 APlayer音乐播放器插件的使用 音乐存储在阿里云OSS
  8. 如何将matlab代码转为C语言(2)--在C++中调用matlab的函数
  9. Nginx进阶篇 :Nginx proxy服务器
  10. Make a Face: Towards Arbitrary High Fidelity Face Manipulation(做个脸:走向任意高保真脸部操纵)