聚类分析(Cluster Analysis)

聚类分析指将物理或抽象对象的集合分组为由类似的对象组成的多个类的分析过程。它是一种重要的人类行为。聚类分析的目标就是在相似的基础上收集数据来分类。聚类源于很多领域,包括数学,计算机科学,统计学,生物学和经济学。在不同的应用领域,很多聚类技术都得到了发展,这些技术方法被用作描述数据,衡量不同数据源间的相似性,以及把数据源分类到不同的簇中。

聚类与分类的不同在于,聚类所要求划分的类是未知的。聚类是将数据分类到不同的类或者簇这样的一个过程,所以同一个簇中的对象有很大的相似性,而不同簇间的对象有很大的相异性。从统计学的观点看,聚类分析是通过数据建模简化数据的一种方法。传统的统计聚类分析方法包括系统聚类法、分解法、加入法、动态聚类法、有序样品聚类、有重叠聚类和模糊聚类等。采用k-均值、k-中心点等算法的聚类分析工具已被加入到许多著名的统计分析软件包中,如SPSS、SAS等。

从机器学习的角度讲,簇相当于隐藏模式。聚类是搜索簇的无监督学习过程。与分类不同,无监督学习不依赖预先定义的类或带类标记的训练实例,需要由聚类学习算法自动确定标记,而分类学习的实例或数据对象有类别标记。聚类是观察式学习,而不是示例式的学习。聚类分析是一种探索性的分析,在分类的过程中,人们不必事先给出一个分类的标准,聚类分析能够从样本数据出发,自动进行分类。聚类分析所使用方法的不同,常常会得到不同的结论。不同研究者对于同一组数据进行聚类分析,所得到的聚类数未必一致。从实际应用的角度看,聚类分析是数据挖掘的主要任务之一。而且聚类能够作为一个独立的工具获得数据的分布状况,观察每一簇数据的特征,集中对特定的聚簇集合作进一步地分析。聚类分析还可以作为其他算法(如分类和定性归纳算法)的预处理步骤。

聚类分析是一个富有挑战性的研究领域,对数据挖掘中聚类分析的一些要求:

  • 可伸缩性(scalability)。实际应用要求聚类算法能够处理大数据集,且时间复杂度不能太高(最好是多项式时间),消耗的内存空间也有限。目前,为了将算法拓展到超大数据库(VLDB)领域,研究人员已经进行了许多有益的尝试,包括:增量式挖掘、可靠的采样、数据挤压(data squashing)等。其中,数据挤压技术首先通过扫描数据来获得数据的统计信息,然后在这些统计信息的基础上进行聚类分析。比如BIRCH 算法中使用CF树就是属于数据挤压技术。

  • 能够处理不同类型的属性。现实中的数据对象己远远超出关系型数据的范畴,比如空间数据、多媒体数据、遗传学数据、时间序列数据、文本数据、万维网上的数据、以及目前逐渐兴起的数据流。这些数据对象的属性类型往往是由多种数据类型综合而成的。

  • 能够发现任意形状的簇。

  • 尽量减少用于决定输入参数的领域知识。

  • 能够处理噪声数据及孤立点。

  • 对输入数据记录的顺序不敏感。

  • 高维性(high-dimensional)。一个数据集可能包含若干维。较高的维数给聚类分析带来两个问题:首先,不相关的属性削弱了数据汇聚的趋势,使得数据分布非常稀疏。尽管这种情况在低维空间中并不多见,但是随着维数的增加,不相关属性的出现概率及数量也会增加,最后导致数据空间中几乎不存在簇。其次,高维使得在低维中很有效的区分数据的标准在高维空间中失效了。如在高维空间中,数据点到最近邻点的距离与到其他点的距离没有多少分别,从而导致最近邻查询在高维空间中不稳定,此时若根据接近度来划分簇,结果是不可信的。

  • 能够根据用户指定的约束条件进行聚类。

  • 聚类结果具有可解释性和可用性。

聚类分析是一种分类技术。与多元分析的其他方法相比,该方法较为粗糙,理论上还不完善,但应用方面取得了很大成功。与回归分析、判别分析一起被称为多元分析的三大方法。

聚类的目的——根据已知数据( 一批观察个体的许多观测指标) , 按照一定的数学公式计算各观察个体或变量(指标)之间亲疏关系的统计量(距离或相关系数等)。 根据某种准则( 最短距离法、最长距离法、中间距离法、重心法等),使同一类内的差别较小,而类与类之间的差别较大,最终将观察个体或变量分为若干类。

根据分类的方法可将聚类分析分为:系统聚类、快速聚类、有序聚类。根据分类的对象可将聚类分析分为:Q型——样品聚类clustering for individuals;R型——指标聚类clustering for variables。

应用示例

from numpy import vstack 
from scipy.cluster.vq import kmeans,vq
from matplotlib.finance import quotes_historical_yahoo_ochl
from datetime import datetime

start = datetime(2014,7,1)
end = datetime(2014,9,30)
listDji = ['AXP','BA','CAT','CSCO','CVX','DD','DIS','GE',
'GS','HD','IBM', 'INTC','JNJ','JPM','KO','MCD','MMM','MRK',
'MSFT','NKE','PFE','PG','T','TRV', 'UNH','UTX','V','VZ','WMT','XOM'] #30家公司代号

'''初始化两个二维数组'''
quotes = [ [0 for col in range(90)] for row in range(30)]
listTemp = [ [0 for col in range(90)] for row in range(30)]

for i in range(30):
quotes[i] = quotes_historical_yahoo_ochl(listDji[i], start, end) #摘录数据,放入quotes

days = len(quotes[0])
for i in range(30):
for j in range(days-1):
if (quotes[i][j][2] and quotes[i][j+1][2] and (quotes[i][j+1][2]>=quotes[i][j][2])): #比较前后两天的收盘价
listTemp[i][j] = 1.0
else:
listTemp[i][j] = -1.0

data = vstack(listTemp)
centroids,_ = kmeans(data,4) #float or double is supported
result,_= vq(data,centroids)
print(result)

原文:https://github.com/KeKe-Li/tutorial