聚类--KM、DBACSN,层次聚类
1. 聚类
对于聚类,关键一步是要告诉计算机怎样计算两个数据点的相似性,不同的算法需要的相似性是不一样的。
1.1. DBSCAN
1.1.1. DBSCAN原理
DBSCAN核心原理就是密度聚类的原理:寻找出稠密的地方,把它们当做一个簇,也就是密度相连的区域,我们把它当成一个簇。 “DBSCAN如何发现簇?”初始,给定数据集D中的所有对象都被为‘unvisited’。DBSCAN随机选择一个未访问的对象p,标记p为‘visited’,并检查p的e-领域是否至少包含MinPts个对象,如果不是,则p被标记为噪声点,否则为p创建一个新的簇C,并且把p的e-领域中的所有对象都放到候选集合N中。DBSCAN迭代地把N中不属于其它簇的对象添加到C中。在此过程中,对于N中标记为‘unvisited’的对象p‘,DBSCAN把它标记为’visited‘并且检查它的e-领域。如果p’的e-领域至少有MinPts个对象,则p‘的e-领域中的对象都被添加到N中。DBSCAN继续添加对象到C,知道C不能再扩展。
1.1.2 粗糙伪代码
radius=半径 points_num=邻近点数 p=随机质心点 c={} """ 以**意:每次计算一次簇就要把数据剔除掉,用剩下的进行密度聚类 """ for 数据 in 数据集: num= 计算每个数据是否属于质心半径内数据数量 if num<points_num: 非质心 else: 计算簇内所有包含的数据
1.2 K-means
1.2.1 K-Means原理
K-means的原理:就是计算每个数据到质心的距离,然后选出来簇后,再计算簇内新的质心,再次计算每个数据到质心的距离,一直迭代。知道新质心和旧质心距离小于某个阈值。
1.2.2 K-means伪代码
# 质心 center=[x1..x5] # 存入簇和其对应数据点的字典 n_datas={} for i in datas: distance_list=[] for j in center: # 计算两个点之间的距离 distance = numpy.sqrt(sum(np.power((i,j),2))) # 把距离存入列表 distance_list.append(distance) # 对列表进行排序,并返回最小距离和其索引 cluster=distance_list.argsort()[0] # 把数据存入到对应的簇内 keys = n_datas.keys() if not cluster in keys: n_datas['{}'.format(cluster)]=[i] else: dict_k = n_datas['{}'.format(cluster)] dict_k.append(i)
1.3 层次聚类
1.3.1 层次聚类的原理
层次聚类,是一种很直观的算法。顾名思义就是要一层一层地聚类,可以从下而上地把小cluster合并聚类,也可以从上而下地将大cluster进行分割。似乎一般用得比较多的是从下而上地聚集。 所谓从下而上地合并cluster,具体而言,就是每次找到最短的两个cluster,然后合并成为一个大的cluster,知道全部合并为一个cluster。整个过程就是建立一个树结构,类似于下图。
那么,如何判断两个cluster之间的距离呢?一开始每个数据点作为一个簇,他们的距离就是这两个点之间的距离,二对于包含不止一个点的cluster就可以选择多种方法了。最常用的,就是average-linkage,即计算两个cluster各自数据点的两两距离的平均值。类似的还有single-linkage、complete-linkage,选择两个cluster中距离最短、最长的一对数据点的距离作为类的距离。这两种不怎么用。 层次聚类较大的有点,就是它一次性得到了整个聚类过程,只要得到上面的聚类数,想要分多少cluster都可以直接根据树结构来得到结果,改变cluster数目不需要再次计算数据点的归属。层次聚类的缺点是计算量比较大,因为每次都要计算多个cluster内所有数据点的两两之间的距离。另外,层次聚类,是贪心算法,得到的是局部最优,不是全局最优,可以通过加入随机效应。
1.3.2 如何确定如何取cluster?
对于层次聚类,可以根据聚类过程中,每次合并的两个cluster的距离来做大概判断。根据一下图可以做个大概的估计,在簇4位置随着聚类步数增加簇量增加,可以得到簇4比较好
1.3.3 层次聚类伪代码
# 计算点与点距离公式 def em(self,A,B): distance = np.sqrt(sum(np.power(A-B,2))) return distance # 计算两个簇中每个数据点与其他数据点的距离,取均值作为两个数据点的距离 # 计算簇与簇之间的距离 def anerageLinkage(self,A,B): total=0.0 for i in A: for j in B: # 计算所有数据点两两之间的距离,具有A*B个 total+=em(i,j) ret = total/(A.shape[0]*B.shape[0]) return ret # 对簇之间的距离进行对比,选取最近的两个合并
1.4 算法之间的优缺点
1.4.1 K-means
K-means的标准: 1.k值得确定,我们必须确定我们算法中需要分几类。 2.计算距离公式,这个公式可以用欧氏距离计算。 3.聚类中心的计算,因为要不断更新聚类中心点需要一个更新策略更新。 优点: 1.k均值算法是解决聚类问题的一种经典算法,算法简单,快速 2.对处理大数据,该算法是相对可伸缩的和高效率的,因为它的复杂度是O(nkt) 3.算法尝试找出使平方误差函数值最小的k个划分。当簇是密集的球状或团装,而 簇与簇之间区别明显时,它的聚类效果很好。 缺点: 1.对K值敏感。k值得选择会在很大程度上影响分类效果。需要进行数据分析 2.对离群点和噪声点敏感。如果上述数据集汇总添加一个噪声点,这个噪声点独立称为一个类。 3.初始聚类中心的选择。K-means是随机选择K个点作为初始的聚类中心。 4.只能聚集凸的数据集,因为是计算连接两个点之间的距离。所以计算的聚类形状只能是球形。研究表明,若采用Bregman距离,则可显著增强此类算法对更多类型簇结构的适用性。 改进: 1.针对K值得选择其问题,主要是K值必须预先设定,并且整个算法执行过程汇总无法更改。此时,可以利用ISODATA算法;当属于某个类别的样本过少,九江这个类别跳出;当这个类别的样本过多的时候,分散程度很大的时候,九江这个特类别分为两个自类。实际应用中,最常用的任然是基于不同的K值,多次运行取平均值 2.针对离群点和噪声点,我们可以使用一些算法,比如RANSAC,LOD等提出离群点。此外基于KM的算法有k-medoids和k-medians 3.对于初始聚类中心点的问题,K-means++不在选择K格局类中心:假设已经选择m个聚类中心(0<M<K),m=1时,随机选择一个聚类中心点;在选取第m+1个点的时候,距离当前m个聚类中心点的中心越远的点,月会以更高的概率被选为第M+1个聚类中心 4.KM是使用欧氏距离来进行测量距离。但是这种方法并不适合所有数据即。只适合那种球形,曹肇SVM中核函数的思想,将样本映射到另外一个特征空间,就可以改善聚类效果。
1.4.2 DBSCAN算法:基于密度的聚类算法
优点: 1.自适应的聚类,不需要提前设定K值大小,可以自适应的做聚类效果。 2.对噪声不敏感。因为该算法能够很好的判断离群点,并且即使判错离群点,对最终的聚类结果也没什么影响 3.能发现任意形状的簇。这是因为DBSCAN是靠不断链接邻域高密度点来发现簇,只需要定义邻域大小和密度阈值,因此可以发现不同形状的簇 4.聚类效果没有偏倚,相对的KM均值初始值对聚类结果有很大影响。 缺点: 1.对两个参数的设置敏感,即圈的半径和阈值。 2.DBSCAN使用固定的参数识别聚类,显然,当聚类的稀疏程度不同,聚类的效果也不同。即数据密度不均匀,很难使用该算法。 3.如果数据样本集雨大,收敛时间越长。此时可以使用KD树优化。
1.4.3 层次聚类
优点: 1.距离和规则的相似度容易定义,限制少。 2.不需要余弦指定聚类数。 3.可以发现类的层次关系 缺点: 1.计算复杂度搞。 2.奇异值也能产生很大影响 3.算法很可能聚类成链状