常见的神经网络是一种监督学习,监督学习的主要特征即为根据输入来对输出进行预测,最终会得到一个输出数值.而非监督学习的目的不在于输出,而是在于对读入的数据进行归类,选取特征,打标签,通过对于数据结构的分析来完成这些操作, 很少有最后的输出操作.
从训练数据的角度来说也是有所区别:监督学习的训练数据为(x,y), 即同时具有输入和输出数值,根据这种输入和输出来判断训练的结果是否正确.
但是非监督学习的数据只有输入数据(x),或者说非监督学习就是要处理这些数据,然后随着新的数据加入再不断进行修改,完成对数据特征提取和区分的要求.
把相同的数据进行归类,这就是非监督学习所作的事情.
下面将介绍两种常用的非监督学习算法:聚类分析和异常检测
本文中需要一定的概率论/高中概率的前置知识
(1)什么是聚类分析
俺举个简单点例子,比如说我们有两个维度的特征值x1 x2,这个时候我们根据特征值把数据点描绘在图片上.
可以很明显地看到,因为各自的特征不同和相似,我们最终可以把原本的数据集合分成两个集群聚类(cluster),我们的目的就是通过算法找到这两个聚类究竟有多少成员,有哪些成员
其中一种古老但是经典的早期算法K-means可以用来解决这个问题
(2)K-means算法
在具体解释这个算法之前,要说明一个概念:集群质心 cluster controids,集群质心代表这些集群的一个中心点.
1.Kmeans的算法第一步就是按照人为的需求,随机分配多个集群质心
2.然后将每个点分配给距离自己最近的质心,组成一个集群
3.集群中的点通过特征值平均,算出一个中心点位置,然后把这个集群的质心移动到这个位置
4.重复 2 3 两个步骤,直到最后质心的距离不发生改变,即可视为集群操作完成
下面将将会使用图片来进行说明,我们一共有三十个数据点,按照特征值划分开
随机分配两个质心(这里假设我们需要的是划分出两个集群,然后接下来是对每个数据点进行归类,将其分配给某个群(严格来说是和距离自己最近的质心打上同样的标记)
将多个数据点分配到具体的集群以后,这个时候暂时就先不用到集群质心cluster controids了
对于每一个集群,我们通过各个分量之间计算平均点的方式,计算出这个集群的集群质心应该在什么位置上
然后将集群质心移动到对应的点上
重复以上两个步骤,最终实现集群质心的固定,到这种程度就可以认为规定数目的集群已经按照要求划分完成
(3)聚类算法的优化
忘记说明一点,kmeans算法的初始化,随机分配集群质心,一般是直接在已有的数据点中生成,而不是真的凭空捏造一个(hhhh).但是不同的随机选取结果,最终可能会导致不同的集群划分结果,甚至可能造成unconverge不收敛现象.
类似监督学习中的代价函数,这里我们同样是存在代价函数,只不过计算方法有一点点区别
Kmeans的代价函数如下
:代表的是第i个数据点所在的群
:代表的是某个群的集群质心
所以这个公式的解释就是:所有点到他们各自所在群的集群质心的距离的二范数(空间距离)的平均值
在比较不同集群算法结果的时候,计算代价函数是比较合理的比较方法
而聚类算法的优化,也是期望代价函数能够降到最低
另外要说的是,不合理无法归一的情况是客观存在的,结局办法有很多,比如重新进行随机点的选取,但是kmeans毕竟还是比较早期的算法.可以选用其他算法或者其他改进模式,这里就不进行赘述了
3.异常检测算法 anomal detect
异常检测算法通常用于一些特殊的情况, 比如一些物体的识别,比如水果,可以按照重量,色泽等等特征来做区分,或者珍珠可以按照半径,色泽等等方式来判断一个珍珠是好是坏.正所谓幸福千篇一律,苦难各有不幸.
我们所遵从的原则是"群体原则",即为服从大多数,大多数具有相同特征的人被称之为正常.
所以因为这样,我们要使用高斯分布这一特性
这个玩意我觉得大多数人应该在高中或者是大学的概率论课程中接触过,在异常检测算法之中,我们会对每一个分量进行高斯分布计算
假设某一批数据有很多特征值
.............................................................
对于每一个分量,例如这个矩阵的第一列,即每个样本的第一个特征值,对于这些数据我们需要计算出方差和平均值,然后就能构建出一个分量的高斯式子
然后对于整体的输入数据来说,某个数据xi想要判断是不是"异常",只需要计算这个向量的高斯数值
(注意一个很有趣的地方,就算这些特征值可能不是独立的,我们这个式子仍然是成立的)
然后通过这样子,判断该数据向量的高斯分布数值是否大于某个阀值,即可直到是不是属于"大多数"
(2)注意事项
1.在训练的时候,训练数据必须全是正常的数据,测试集合中需要包含一些
2.有些特征可能并不是高斯分布,需要我们对数据进行适当的方所处理
3.不是二维分布不是二维聚类!二位聚类是根据两种不同的特征值划分出两种截然不同的集群,两个群中的元素则都有各自相同的部分.
而异常检测不一样,异常检测做到的是区分"大多数"和"异端"