一、基本概念
1)聚类
将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类。由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异。聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法。聚类分析起源于分类学,但是聚类不等于分类。聚类与分类的不同在于,聚类所要求划分的类是未知的。聚类分析内容非常丰富,有系统聚类法、有序样品聚类法、动态聚类法、模糊聚类法、图论聚类法、聚类预报法等。
2)K-means算法
K-means算法是集简单和经典于一身的基于距离的聚类算法采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。
该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。
通过迭代寻找k个类簇的一种划分方案,使得用这k个类簇的均值来代表相应各类样本时所得的总体误差最小。
k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
k-means算法的基础是最小误差平方和准则,
其代价函数是:
代价函数公式式中,μc(i)表示第i个聚类的均值。
各类簇内的样本越相似,其与该类均值间的误差平方越小,对所有类所得到的误差平方求和,即可验证分为k类时,各聚类是否是最优的。
上式的代价函数无法用解析的方法最小化,只能有迭代的方法。
二、练习
1)聚类练习
class Cluster(object):
def init(self, examples):
self.examples = examples
self.centroid = self.computeCentroid()
def update(self, examples):
oldCentroid = self.centroid
self.examples = examples
self.centroid = self.computeCentroid()
return oldCentroid.distance(self.centroid)
def computeCentroid(self):
vals = pylab.array([0.0]*self.examples[0].dimensionality())
for e in self.examples: #计算均值
vals += e.getFeatures()
centroid = Example('centroid', vals/len(self.examples))
return centroid
def getCentroid(self):
return self.centroid
def variability(self):
totDist = 0.0
for e in self.examples:
totDist += (e.distance(self.centroid))**2
return totDist
def members(self):
for e in self.examples:
yield e
def __str__(self):
names = []
for e in self.examples:
names.append(e.getName())
names.sort()
result = 'Cluster with centroid '\
+ str(self.centroid.getFeatures()) + ' contains:\n '
for e in names:
result = result + e + ', '
return result[:-2]
2)K-means算法练习
from numpy import *
import time
import matplotlib.pyplot as plt
def euclDistance(vector1, vector2):
return sqrt(sum(power(vector2 - vector1, 2)))
def initCentroids(dataSet, k):
numSamples, dim = dataSet.shape
centroids = zeros((k, dim))
for i in range(k):
index = int(random.uniform(0, numSamples))
centroids[i, :] = dataSet[index, :]
return centroids
def kmeans(dataSet, k):
numSamples = dataSet.shape[0]
clusterAssment = mat(zeros((numSamples, 2)))
clusterChanged = True
centroids = initCentroids(dataSet, k)
while clusterChanged:
clusterChanged = False
for i in xrange(numSamples):
minDist = 100000.0
minIndex = 0
for j in range(k):
distance = euclDistance(centroids[j, :], dataSet[i, :])
if distance < minDist:
minDist = distance
minIndex = j
if clusterAssment[i, 0] != minIndex:
clusterChanged = True
clusterAssment[i, :] = minIndex, minDist**2
for j in range(k):
pointsInCluster = dataSet[nonzero(clusterAssment[:, 0].A == j)[0]]
centroids[j, :] = mean(pointsInCluster, axis = 0)
print 'Congratulations, cluster complete!'
return centroids, clusterAssment
def showCluster(dataSet, k, centroids, clusterAssment):
numSamples, dim = dataSet.shape
if dim != 2:
print "Sorry! I can not draw because the dimension of your data is not 2!"
return 1
mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
if k > len(mark):
print "Sorry! Your k is too large! please contact Zouxy"
return 1
for i in xrange(numSamples):
markIndex = int(clusterAssment[i, 0])
plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
for i in range(k):
plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
plt.show()
网友评论