机器学习(五)

聚类算法

这是这门课讲述的第一个无监督学习算法。
在无监督学习中我们的数据并不带有任何标签,在无监督学习中要做的是,将这系列无标签的数据输入到算法中,然后我们要让算法找到一些隐含在数据中的结构。

  • k均值算法(k-means)算法是现在最热门,最为广泛运用的聚类算法:
    1. 假设我有一个无标签的数据集如图所示,并且我想将其分为两个簇,现在我执行k均值算法。
      1
    2. 第一步是随机生成两点,这两点就叫做聚类中心也就是图上的两个叉,选两个聚类中心是因为我想分成两个簇。k均值算法是一个迭代算法,它会做两件事情,第一个是簇分配,第二个是移动聚类中心。
      2
    3. 第一步簇分配,也就是说我要遍历每个样本,也就是图上的每个绿点,然后根据每一个点,是与红色聚类中心更近,还是与蓝色聚类中心更近,来将每个数据点分配给两个聚类中心之一。3
    4. 第二步移动聚类中心,我们要做的是将两个聚类中心,也就是红色和蓝色的叉,将其移动到同色的点的均值处,因此我们要做的是找出所有红色的点然后算出它们的均值,也就是所有的红色点的平均位置,然后把红点的聚类中心移动到这里,蓝色聚类中心也一样。
      4
    5. 完成以上步骤之后再次进行一次簇分配, 当簇不再改变时,就可以说k均值已经聚合了。
  • 常见应用:它可以用来解决分离不佳的簇的问题,举例:t恤尺码。

k均值的优化目标函数

了解k均值的优化目标函数,这将能帮助我们对学习算法进行调试,确保k均值算法运行正确。
我们可以运用它帮助k均值算法找到更好的簇,并且避免局部最优解。
在k均值算法中,用大写的K代表簇的数量,小写的k代表聚类中心的下标,小写的k取值范围是1到K。

  • 假设 x ( i ) x^{(i)} x(i)被划分到第五个簇,意思是, c ( i ) = 5 c^{(i)} = 5 c(i)=5 ,因此 μ c ( i ) \mu_{c^{(i)}} μc(i)就等于 μ 5 \mu_5 μ5,也就是第五个簇的聚类中心。k均值聚类算法的优化目标如下:
    J ( c ( 1 ) , . . . , c ( m ) , μ 1 , . . . , μ k ) = 1 m ∑ i = 1 m ∣ ∣ x ( i ) − μ c ( i ) ∣ ∣ 2 J(c^{(1)},...,c^{(m)},\mu_1,...,\mu_k) = \frac{1}{m}\sum_{ i =1}^m||x^{(i)} - \mu_{c^{(i)}}||^2\\ J(c(1),...,c(m),μ1,...,μk)=m1i=1m∣∣x(i)μc(i)2
    它的参数会随着算法的运行不断变化, k均值算法要做的事情就是找到参数 c ( i ) c^{(i)} c(i) μ i \mu_i μi,也就是能够最小化 代价函数J的 c c c μ \mu μ,这个代价函数有时也叫失真代价函数或者k均值算法的失真。
  • 失真函数可以用来调试k均值算法,并帮助我证明k均值是收敛的并且能正常运行。

k均值算法的随机初始化

对于初始化聚类中心有几种不同的方法。
事实证明,有一种算法比大多数可能考虑到的方法更值得推荐。

  • K均值算法最终可能会收敛得到不同的结果,这取决于聚类的初始化状态,随机初始化状态不同,K均值最后可能会得到不同的结果,具体而言,K均值算法可能会落在局部最优。
    因此如果你担心K均值算法落到局部最优,如果你想让K均值算法找到最有可能的聚类,我们可以尝试多次随机初始化。典型的初始化次数是50到1000之间,对于每一次初始化,我们都运行k均值算法 ,用我们得到的聚类分配和聚类中心来计算代价函数。最后在这些次数中得到的结果中选择代价最小的一个,也就是畸变值最小的一个。
    如果聚类次数在2到10之间的话,那么多次随机初始化,通常能够保证你能找到较好的局部最优解。
  • 如果K比10大很多,如果你想要找到成百上千个聚类那么多次随机初始化就不会有太大改善,更有可能你第一次随机初始化就会给你相当好的结果。多次随机初始化会给你一个稍微好一点的结果,但是不会好太多。但是如果K相对较小的话,随机初始化会有较大的影响,可以保证你很好地最小化畸变函数,并且能得到一个很好的聚类结果。

如何选择聚类数量

如何选择参数K的值,这个问题没有什么好的答案也没有能自动处理的办法,目前为止,用来决定聚类数量,最常用的方法,仍然是通过观察可视化的图,或者是通过观察聚类算法的输出等等。
这也是无监督学习的一部分,数据没有标签,因此并不总是有一个明确答案,也因为这个原因,用一个自动化的算法,来选择聚类数量是很困难的。
下面介绍一种选择聚类数量的方法,名为肘部法则。

  • 随着聚类数量的增多,畸变值下降,我们可能会得到一条类似于这样的曲线,如果你观察这条曲线,“肘部法则”就是观察这个图,可以看到这个曲线有一个“肘部”。
    在这里插入图片描述
    事实证明,肘部法则并不那么常用,原因之一是,在实际运用到聚类问题上时,往往最后你会得到一条看上去相当模糊的曲线,也许就像这样,看上去畸变值是连续下降的,但是没有一个清晰的拐点。
    在这里插入图片描述
  • 另一种选择K值的思路是,通常人们使用K均值聚类是为了得到一些聚类用于后面的目的,或者说是下游目的,也许你想用K均值聚类来做市场分割,就像我们之前说的T恤尺寸的例子,也许你想用K均值来更好地组织计算机集群,或者为了别的目的,学习聚类,如果后续目的如市场分割,能给你一个评估标准,那么决定聚类的数量更好的方式是,看哪个聚类数量能更好地应用于后续目的,举例:T恤售卖。

降维

这里开始讨论第二种类型的无监督学习问题。
下举例说明。

  1. 假设我们收集了一个数据集,它有很多很多的特征。我只在这里画出其中两个特征,假如对我们来说, 这两个特征实际上是一个作用,一个是某物体的厘米长度,另一个是同一物体的英寸长度,这实际上是一种高度冗余的表示。对于这两个单独的特征,表示的都是基本长度,也许我们想要做的是,把数据从二维减少到一维,来减少这种冗余。
  2. 假如你想对飞行员们做一个测试,你可能会有一个特征 x 1 x_1 x1,代表这些飞行员的技能;另一个特征 x 2 x_2 x2可能是飞行员的快乐程度,也就是他们享受飞行的程度。那么这连个特征可能是高度相关的,不过你真正关心的可能是图中直线所示方向上的,一个不同的,用来真正测量飞行员能力的特征,我给他取名叫aptitude。
    在这里插入图片描述
    现在我把不同的样本用不同的颜色标出来,在这时,通过降维,我的意思是,我想找出这条线,这条看起来大多数样本所在的线,所有的数据都投影到了我刚画的线上,通过这种做法我能测量出每个样本在线上的位置,现在我能做的就是建立新特征 z 1 z_1 z1。这个新特征它能够指定绿线上每一个点的位置,意思就是假设原来的样本 x ( i ) x^{(i)} x(i)需要一个二维的向量来表示,现在我可以用 z ( i ) z^{(i)} z(i)来表示它,它是一个实数。这样就能把内存的需求减半,或者说数据空间需求减半。这也将允许我们让学习算法运行得更快,同时这也是数据压缩中更有趣的一种应用。
    在这里插入图片描述
  3. 这个例子展示如何把数据从三维降到二维。 降维的方法是,由于大多数的数据大概都分布在一个平面内,所以我们这时降维的方法就是把所有数据都投影到一个二维平面上,最后为了指定这个点在平面中的位置,我们需要两个数字,不妨叫做 z 1 z_1 z1 z 2 z_2 z2,来指定这个平面中点的位置。 即我们的数据可以用二维向量 z ( i ) z^{(i)} z(i)来表示。
  • 注意,在降维例子中,我们可能会有多达1000维或者说1000D的数据,然后我们需要把数据降到100维,但是由于绘图的局限性,我无法在幻灯片中展示。故举例从三维降到二维,从二维降到一维。

  • 降维不仅可以用于压缩数据还可以用于可视化数据。

PCA

PCA,也叫主成分分析,它可以用于降维操作,也可以用来实现数据可视化。
它会找一个低维平面,然后将数据投影在上面。
下面举例说明。

  • 这个例子中是条直线,使这些蓝色小线段长度平方最小,这些蓝色线段的长度有时也称投影误差,所以PCA所做的就是,他会试图寻找一个投影平面对数据进行投影,使得能最小化这个距离,另外在应用PCA之前常规的做法是先进行均值归一化和特征规范化,使得特征量 x 1 x_1 x1 x 2 x_2 x2其均值为0,并且其数值在可比较的范围之内,本例中已进行过处理。为了进行对比,图中增加了另一条能够进行数据投影的品红色直线。
    如图,如果用品红色直线来投影这些数据的话,它的方向相当糟糕,数据投影上去后这些蓝色的线段将会很大,因此这些点不得不移动很长一段距离,才能投影到这条品红色的直线上,所以PCA算法会选择红色直线而不是品红色直线。
    1
  • 更通常的是,我们会有N维的数据,并且我们想其降到K维,这种情况下我们不只是想找单个向量,来对数据进行投影,而是想寻找K个方向来对数据进行投影,来最小化投影误差,我们要找出一组向量, u ( 1 ) , u ( 2 ) , . . . , u ( k ) u^{(1)},u^{(2)},...,u^{(k)} u(1),u(2),...,u(k) 。我们要做的是将这些数据投影到这K个向量展开的线性子空间上,即寻找一个K维平面 ,我们可以用K个方向来定义平面中这些点的位置。
  • 线性回归与PCA的关系:
    • PCA不是线性回归,尽管看上去有一些相似,但是它们确实是两种不同的算法,对于下图,在线性回归中我们要做的是拟合一条直线来最小化点和直线之间的平方误差,是某个点与假设的得到预测值之间的距离(垂直距离);而在PCA中,它要做的是试图最小化,这些蓝色直线的长度,它们是倾斜地画出来的,实际上它们是最短的正交距离,也是点x与红色直线之间的最短距离,同时,数据集不同就会产生迥然不同的效果。
    • 更一般的是,当你处理线性回归时,我们要试图预测一个特别的变量y,线性回归所要做的是,用所有的x值来预测y,然而在PCA中,没有区别对待,没有什么特殊的变量y是我们要预测的,相反我们的一系列特征 x 1 , x 2 , . . . x n x_1,x_2,...x_n x1,x2,...xn都是同等对待。
  • 使用PCA算法的步骤:
    • 首先进行数据预处理,给定一个交易例子的集合,一定要做的一个重要的事是,执行均值标准化,依据于你的数据,可能也要进行特征缩放,这两个过程即在我们有监督学习中均值标准化过程与特征缩放的过程是很相似的,实际上确实是相同的过程。
      在这里插入图片描述
    • 为了把N维的数据降到K维度,我们首先要做的是计算这个叫做协方差的,这个协方差通常用希腊字母表中的大写Sigma表示。(希腊字母Sigma被用来表示一个矩阵,不要混淆它和求和标记。)
      Σ = 1 m ∑ i = 1 n ( x ( i ) ) ( x ( i ) ) T \Sigma = \frac{1}{m}\sum_{i=1}^n(x^{(i)})(x^{(i)})^T Σ=m1i=1n(x(i))(x(i))T
      后续省略…
  • 如何选择k (没看懂,这里的k不知道是什么)在这里插入图片描述

如何从低维表示z恢复到高维表示x

(这部分也没看懂 待补充)

如何选择维度K的值

在某些情况下PCA可以加快算法的执行效率,下面讲解具体如何去做,并给出一些如何去应用PCA算法的相关建议。
使用PCA来加速学习算法的方法,我通常使用PCA算法对监督学习算法进行加速,假设你有一个监督学习问题,注意这个监督学习算法有输入x和标签y,假设在你的例子中 x ( i ) x^{(i)} x(i)是有非常高的维度的比如说10000维的特征向量,在实际中这可能是计算机视觉的问题,对于这种高维向量,运行学习算法时将变得非常慢,假如你要使用10000维的特征向量进行logistic回归,或者输入神经网络,或者支持向量机,或其他你想要的操作,因为数据量太大,将会使得你的学习算法运行速度非常慢,此时用PCA算法可以减少数据的维度从而使得算法运行更加高效。

  • 首先检查已经被标记的训练集,并抽取输入,我们抽取出这些x,把y先临时放一边,我们就得到了一个无标签的训练集,从 x ( 1 ) x^{(1)} x(1) x ( m ) x^{(m)} x(m),可能是10000维的数据,接着我使用PCA得到原始数据的低维表示,它们不再是10000维的特征向量,而是变成了1000维的特征向量,这样就给了我们一个新的训练集, z ( 1 ) z^{(1)} z(1) y ( 1 ) y^{(1)} y(1)对应,相似的 z ( 2 ) z^{(2)} z(2) y ( 2 ) y^{(2)} y(2)等等,直到 z ( m ) z^{(m)} z(m) y ( m ) y^{(m)} y(m),最终我可以把这个低维的训练集输入一个学习算法,可能是神经网络,或者是logistic回归算法,我可以学习假设函数H,使用这些输入,这些低维的输入z,尝试去进行预测。如果使用logistic回归,我会训练一个假设函数,输出是 1 1 + e − θ T z \frac {1}{1+e^{-\theta^Tz}} 1+eθTz1,输入一个z向量就可以尝试去进行预测,最后如果你有一个新样本,可能是一个新的测试样本x,你要做的是将测试样本x通过PCA的映射关系进行映射获得对应的z,获得z后,把z代入到假设函数中,这个假设函数,就会对输入x进行预测,最后要注意一点,PCA所做的是定义一个从x到z的映射,这个从x到z的映射只能通过在训练集上运行PCA来定义,具体而言,PCA学习的这个映射所做的就是计算一系列参数进行特征缩放和均值归一化,它还计算矩阵U_reduced。运行PCA时,我们应该只在训练集上拟合这些参数,而不是交叉验证集或者在测试集上,然后找到参数来进行特征缩放或均值归一化,以及划分特征的合适的缩放规模。在训练集上,找到所有这些参数后,你可以把这个映射用在交叉验证集或者测试集的其他样本中。
    • 注意:在这个例子中,我讲了将数据从10000维减少到1000维,实际上这并不是不切实际的,在许多问题上,我们的确能减少数据的维度,大概可以减少到 1 5 \frac{1}{5} 51或者 1 10 \frac{1}{10} 101,而且仍然保留大部分的方差,几乎不影响性能。比如说分类精度,几乎不影响学习算法的分类准确度。
      而且使用较低的维度数据,我们的学习算法通常可以运行得更快。
    • 注意:PCA不是防止过拟合的好方法,遇到过拟合建议选择正则化。

异常检测算法

当我们建立的x的模型概率之后,对于新的数据,也就是 x t e s t x_test xtest,如果概率p低于阈值 ϵ \epsilon ϵ, 那么就将其标记为异常;反之,如果大于等于给定的阈值 ϵ \epsilon ϵ,我们就认为它是正常的。
异常检测算法最常见的应用是欺诈检测,同时它也可以应用于工业生产领域;数据中心的计算机监控等等。

  • 高斯分布

高斯分布,也被称为正态分布。

下面将用高斯分布来推导异常检测算法。
假设x是一个是实数的随机变量,x是一个实数。如果x的概率分布服从高斯分布,其中均值为 μ \mu μ,方差为 σ 2 \sigma^2 σ2,那么将它记作随机变量 x ∼ N ( μ , σ 2 ) x\sim N(\mu,\sigma^2) xN(μ,σ2)N表示normal, σ \sigma σ是方差,它确定了高斯分布概率密度函数的宽度。
根据最大似然估计, μ = 1 m ∑ i = 1 m ( x ( i ) − μ ) 2 \mu = \frac{1}{m}\sum_{i=1}^m(x^{(i)}-\mu)^2 μ=m1i=1m(x(i)μ)2
σ 2 = 1 m ∑ i = 1 m ( x ( i ) − μ ) 2 \sigma^2 = \frac{1}{m}\sum_{i=1}^m(x^{(i)}-\mu)^2 σ2=m1i=1m(x(i)μ)2

整理如下,异常检测算法:
Step1:选择特征量,或是想出一些特征量 x j x_j xj,它能帮我们指出那些反常的样本。意思就是尝试提出一些特征,这样当有一个反常用户在你的系统中做一些不正当行为时,或对于飞机引擎这个例子,当飞机引擎出现了一些奇怪的问题时,选择这样的特征 x j x_j xj ,当出现异常样本时,特征值会异常地特别大,或者异常地特别小。但通常来说,还是选择那些能够描述你所想的,能够描述你所收集的数据的一般特性的特征。
Step2:给出训练集,即m个未做标记的样本,之后我们进行参数拟合, μ 1 \mu_1 μ1 μ n \mu_n μn σ 1 2 \sigma_1^2 σ12 σ n 2 \sigma_n^2 σn2
Step3:最后我们给出一个新案例,当你有一个全新的飞机引擎时,你要想知道这个飞机引擎是否异常,我们要做的就是计算p(x)的值。
p ( x ) = ∏ j = 1 n p ( x j ; μ j , σ j 2 ) = ∏ j = 1 n 1 2 π σ j exp ⁡ ( − ( x j − μ j ) 2 2 σ j 2 ) p(x) = \prod_{j=1}^np(x_j;\mu_j,\sigma_j^2) = \prod_{j=1}^n\frac{1}{\sqrt{2\pi}\sigma_j}\exp(-\frac{(x_j-\mu_j)^2}{2\sigma_j^2}) p(x)=j=1np(xj;μj,σj2)=j=1n2π σj1exp(2σj2(xjμj)2)
如果最后这个概率值p(x)很小,那么就将这一项标注为异常。

  • 如何评估一个异常检测算法

实数评估的主要思想是,当你为某个应用开发一个 学习算法时,你需要进行一系列的选择,比如选择使用什么特征等等,如果你有某种方法,通过返回一个实数来评估你的算法,那么对这些选择作出决定往往会容易得多。
比如你需要决定现在有一个新的特征,该不该纳入这个特征?如果你分别在纳入该特征和不纳入该特征情况下运行算法,然后算法返回一个数字,来告诉你这个特征对算法的影响是好是坏。这样的话,你就能更好地决定是纳入还是不纳入该特征。

  • 为了能够快速地开发出这样一个算法评估系统,这里有一个很好的方法来评估一个异常检测系统。
    假设我们有一些带标签的数据,到目前为止,我们都把异常检测看作是一个无监督学习问题,因为用的是无标签的数据。但如果你有一些带标签的数据来指明哪些是异常样本,哪些是正常样本,这就是我们认为的能评估异常检测算法的标准方法。
    还是飞机引擎的例子,假如我们有一些带标签的数据代表异常样本,代表这批引擎是异常的,有缺陷或者其他怪毛病。同时我们还有一些无异常的样本,也就是完全正常的样本。我用y=0来表示这些无异常或者说正常的样本,y=1来表示一场样本,那么异常检测算法的开发过程以及评估方法如下所示:
    1. 我们先假设有一训练集,我们把该训练集看作是无标签的,所以它是一个很大的正常样本的或者说无异常样本的集合,通常来说我们把它看作无异常样本,即使是溜进去了一些异常样本也没关系。
    2. 接下来我们要定义一个交叉验证集和测试集,用来评估这个异常检测算法,具体来说,对交叉验证集和测试集,我们假设在交叉验证集和测试集中包含一些已知是异常的样本。所以在测试集中,我们有一些标签是y=1的样本。
    3. 因为我们的数据很倾斜,y=0的情况很常见,那么分类正确率就不是一个好的评价指标。我们可以用计算真阳性,假阳性,假阴性,真阴性或者计算出算法的精度以及召回率,使用F值等方式评估你的异常检测算法在交叉验证和测试集样本中的表现。
    4. 之前在异常检测算法中我们还有一个参数 ϵ \epsilon ϵ,它用来决定什么时候把一个样本当作是异常样本的一个阈值。所以如果你有一个交叉验证集,一个选择参数 ϵ \epsilon ϵ的方法就是尝试去使用许多不同的 ϵ \epsilon ϵ值,然后从中选择一个 ϵ \epsilon ϵ值,使得该值能够最大化F值或者在其他方面有良好表现。一般来说使用训练集,交叉验证集和测试集的方法是,当我们进行决策时,比如决定要不要纳入某个特征,或者定义参数 ϵ \epsilon ϵ作为阈值。然后我们就能在交叉验证集中评估算法,然后做出决策,例如用哪些特征,怎么设置 ϵ \epsilon ϵ值。
    5. 找到合适的 ϵ \epsilon ϵ值后,我们就能用最后的模型来评估算法,在测试集中对算法进行最后的评估。

异常检测算法vs监督学习

下面将分析什么时候该使用异常检测算法,什么时候该使用监督学习算法。
以及两个算法的区别。

  • 选异常检测算法:
    • 如果你遇到了一个问题,它的正常例子数量很少,那么你可以考虑使用一个异常检测算法。所以如果有0到20个,可能最多到50个正样本,这是个很典型的数量,通常情况下,我们只有非常少量的正样本。接下来我们保存这些正样本用于交叉验证集和测试集。我们可以用庞大的负样本来拟合p(x)的值,因此在许多异常检测应用中有这样一个思想,你有很少的正样本和很多的负样本,当我们在处理,估计p(x)的值,拟合所有的高斯参数的过程中,我们只需要负样本就够了。
    • 样本中有许多不同类型的异常,而正样本数量较少,很难从正样本中去学习异常是什么,尤其是未来可能出现的异常。可以在你的正样本中,你可能已经了解5个或10个或20个航空发动机发生故障的情况,但可能到了明天你需要检测一个全新的集合,一种新类型异常,一种全新的飞机发动机出现故障的情况,而且你之前从来就没有见过,如果是这种情况,那么更有可能的是对负样本用高斯分布模型p(x)来建模,而不是费尽心思,对正样本建模。因为明天的异常可能与你至今为止见过的情况完全不同。
  • 选监督学习算法:
    • 在合理范围内有大量的正样本和负样本时,更合适使用监督学习。
    • 有足够的正样本或者是已经有一个能识别正样本的算法,尤其是假如你认为,未来可能出现的正样本,与你当前训练集中的正样本类似,那么,那种情况下,使用一个监督学习算法更合理。它能从大两正样本和大量负样本中学到相应特征,并且能够尝试区分正样本和负样本
  • 使用什么特征来实现异常检测算法:在我们的异常检测算法中,我们所做的一件事就是使用高斯分布,来对特征建模,假设其中函数 x j x_j xj的期望是 μ j \mu_j μj,方差是 σ 2 \sigma^2 σ2,所以我经常做的一件事就是画出数据,或者用直方图表示数据,以确保这些数据在进入算法前看上去比较接近于高斯分布。即使你的数据不是高斯分布它也可以正常地运行,这只是一种检查,换句话说,即使数据不是高斯分布,算法往往也能正常运行,但是如果我的数据画出来不像一条钟形曲线,这是一个非常不均匀的分布,他的峰值分散在一边,如果我的数据是这样的话,我通常会对数据进行一些不同的转换,使得它看上去更接近高斯分布。虽然即使你不这么做算法也能运行,但如果你使用这些转换,使你的数据更接近高斯分布的话,那么算法也许能运行的更好。
  • 如何得到异常检测算法的特征:我通常用的办法是通过一个误差分析步骤,这跟我们之前讨论监督学习算法的时误差分析步骤是类似的。我们先完整地训练出一个算法,然后在一组交叉验证集上运行算法然后找出那些预测出错的样本,并看看我们能否找到一些其他的特征来帮助学习算法,让那些在交叉验证集中判断出错的样本表现得更好。
  • 一些思考:我选择特征的方法是我会选那些既不会特别大也不会特别小的特征。对于那些我认为很可能异常的样本,我们还是使用监控数据中心的计算机的例子。假设一个数据中心里,你有很多台电脑,也许有成千上万台,我们想要知道的是如果有一台电脑出现故障,这里给了几种可选的特征,包括占用内存,磁盘每秒访问次数,CPU负载,网络流量,现在比如说,我怀疑某个出错的情况,在我的数据集中,我的CPU负载和网络流量应该互为线性关系。可能我运行了一组网络服务器,如果其中一个服务器正在服务多个用户,那么我的CPU负载和网络流量都很大,但现在比如说,我怀疑其中一个出错的情形是,我的计算机在执行一个任务时,进入了一个死循环。如果我认为其中一个出错的情况是其中一台机器或者说其中一台服务器的代码 执行到一个死循环卡住了,因此CPU负载升高,但网络流量没有升高,因为只是CPU执行了较多的工作所以负载比较大。在这种情况下,要检测出异常我可以建立一个新的特征 x 5 x_5 x5,代表 C P U 负载 网络流量 \frac{CPU负载}{网络流量} 网络流量CPU负载,那么这时 x 5 x_5 x5会有一个异常大的值。

异常检测算法的延伸

这个延伸会用到多元高斯分布,它有一些优势,也有一些劣势。它能捕捉到一些之前的算法也检测不出来的异常。

  • 假设我们有图上这些没有标签的数据,我要使用数据中心的监控机的例子,数据中心监控计算机两个特征变量分别是 x 1 x_1 x1是CPU的负载, x 2 x_2 x2可能是内存使用量。如果我把这两个特征变量当作高斯分布来建模。现在假如说,在测试集中有一个这样的样本,在这个绿色叉的位置,它的 x 1 x_1 x1值是0.4左右, x 2 x_2 x2值是1.5左右,现在观察这些数据,看起来它们大部分都在这个范围内,所以这个绿色叉离这里看到的任何数据都很远。看起来它应该被当做一个异常数据,在好的样本数据中,看起来CPU负载和内存使用量是彼此线性增长的关系,所以如果我有一台机器,CPU使用量很高,那么内存使用量也会很高。但是这个绿色样本看起来CPU负载很低,但是内存使用量很高。跟我训练集中的其他样本都不同,看起来它应该是异常的。但在图上这个点看起来不是很异常,所以异常检测算法不会将这个点标记为异常。我们发现异常检测算法不能意识到这个蓝色椭圆所表示的好样本概率高的范围,相反,它认为里面部分样本是高概率的,外面一些的圈里面的样本是好样本的概率低一些,而最外面的一圈的样本概率更低。它认为那里的绿色叉是好样本的概率挺高。具体来说,它倾向于认为所有在区域中的,在我画的这个圈上的样本都具有相同的概率,它并不能意识到这边的其实比那边的概率要低很多。为了解决这个问题,我们要开发一种改良版的异常检测算法,要用到多元高斯分布或者叫多元正态分布。
    A
  • 多元高斯分布:
    我们有特征变量x,它属于 R n \R^n Rn,我们不要为 p ( x 1 ) , p ( x 2 ) p(x_1),p(x_2) p(x1),p(x2)分别建模,而要建立一个整体的 p ( x ) p(x) p(x)模型,就是为所有 p ( x ) p(x) p(x)建立统一的模型。
    多元高斯分布的参数是向量 μ \mu μ μ ∈ R n \mu ∈ \R^n μRn)和一个n*n的矩阵 Σ \Sigma Σ,它被称为协方差矩阵。它类似于我们之前在学习PCA,也就是主成分分析算法的时候所见到的协方差矩阵,为了完整起见,下面写出多元高斯分布的公式(这个公式没必要记,随时可以查),即
    在这里插入图片描述
  • 开发一个异常检测算法的步骤:
    1. 首先用我们的数据集来拟合该模型(设定 μ \mu μ Σ \Sigma Σ来拟合 p ( x ) p(x) p(x)
    2. 接下来当你有一个新样本x,即一个测试样本,得到这个样本之后我们需要用多元高斯分布的公式来计算 p ( x ) p(x) p(x),如果得到 p ( x ) p(x) p(x)很小( p ( x ) < ϵ p(x)<\epsilon p(x)<ϵ),就标记该样本为异常。
  • 多元高斯分布模型和原始模型的关系:原始模型就是 p ( x 1 ) , p ( x 2 ) p(x_1),p(x_2) p(x1),p(x2) p ( x n ) p(x_n) p(xn)的乘积,即
    p ( x ) = p ( x 1 ; μ 1 , σ 1 2 ) × p ( x 2 ; μ 2 σ 2 2 ) × . . . × p ( x n ; μ n , σ n 2 ) p(x) = p(x_1;\mu_1,\sigma_1^2)\times p(x_2;\mu_2\sigma_2^2)\times...\times p(x_n;\mu_n,\sigma_n^2) p(x)=p(x1;μ1,σ12)×p(x2;μ2σ22)×...×p(xn;μn,σn2)
    不过确实可以用数学方法来推导多元高斯模型,和这个原始模型之间的区别。多元高斯模型的轮廓(等高线)总是轴对齐的。可以证明原始模型就是某种特殊情况下的多元高斯分布,这种情形就是,当它的协方差矩阵 Σ \Sigma Σ在非对角线上都是0的时候,具体地说,这个协方差矩阵 Σ \Sigma Σ,它的对角线上是 σ 1 2 , σ 2 2 . . . , σ n 2 \sigma_1^2,\sigma_2^2...,\sigma_n^2 σ12,σ22...,σn2,在非对角线上的元素全为0,此时这两个模型会完全相同。

原始模型VS多元高斯模型

原始模型使用得更频繁一些,多元高斯模型用得要少一些,但它在捕捉特征间的关系方面有着很多优点。

  • 假设你想进行异常检测,你有一些不同的特征 x 1 , x 2 x_1,x_2 x1,x2等,你想通过异常的组合值来捕捉异常样本。比如在之前的例子中,我们有这样的样本,它出现异常通常是在CPU负载以及内存使用有着异常的组合值的时候。如果你用原始模型来捕捉这一点,你就需要创建一个额外的特征,比如令新特征 x 3 = x 1 x 2 x_3 = \frac{x_1}{x_2} x3=x2x1来捕捉异常的组合值,因为 x 1 x_1 x1 x 2 x_2 x2组合值出现异常的时候,可能 x 1 x_1 x1本身和 x 2 x_2 x2本身看起来都是很正常的值。如果你花费时间来手动创建这样一个新特征,原始模型就能运行得很好,而对比下来,多元高斯模型就能自动地捕捉这种不同特征之间的关系。
  • 不过原始模型也有它自己的优点,原始模型的一个巨大优势就是,它的计算成本比较低,换一种说法就是它能适应巨大规模的n,即适应数量巨大的特征。而相比之下, 多元高斯模型中需要计算 Σ \Sigma Σ矩阵的逆矩阵,而 Σ \Sigma Σ是一个 n × n n \times n n×n矩阵,如果它计算的 Σ \Sigma Σ是个100000 × \times × 100000的矩阵,那么计算成本,将会非常高昂,所以多元高斯模型能适应的n值的范围比较小。
  • 最后对于原始模型,即使你有一个较小的,有一定相关性的训练集,也能顺利运行,这是一个较小的无标签样本,用来拟合模型 p ( x ) p(x) p(x),即使n的值只有50,100这样,它也能工作得很好。而对于多元高斯分布,这个算法有一些数学性质,也就是你必须保证m>n,也就是样本的数量要大于你特征的数量,如果在估计参数时,我们不能满足这个数学性质,那么这个矩阵就会是不可逆的,或者说这会是个奇异矩阵,你无法使用多元高斯模型,除非你对它进行修改。我在这方面有一个原则就是,我会使用多变量高斯模型,当且仅当m远大于n,这也算是一种狭义的数学要求,在实践中我会用多元高斯模型,仅当m比n大很多的时候,假如m ≥ \geq 10n,那么这个时候我就会使用了。如果不能满足这一点,那么多元高斯模型就会有很多参数,因为 Σ \Sigma Σ是个 n × n n \times n n×n的矩阵,所以它大概会有 n 2 n^2 n2个参数,因为它是个对称矩阵,实际上参数的数量更接近于 n 2 2 \frac {n^2}{2} 2n2,但这还是很多,所以你要保证你有一个相当大的m值,确保你有足够的数据来拟合这些变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值