1. 聚类算法
聚类:数据对象的集合
-
在同一个聚类中的对象彼此相似
-
不同聚类中的对象则差别较大
聚类分析 -
将物理或抽象对象的集合分组成为由类似的对象组成的多个类的过程
-
聚类是一种无指导的学习:没有预定义的类别,观察式学习
聚类分析的典型应用 -
在GIS系统中,对相似区域进行聚类,产生主题地图
-
检测空间聚类,并给出它们在空间数据挖掘中的解释
-
图像处理
-
商务应用中,帮市场分析人员发现不同的顾客群
-
对WEB日志的数据进行聚类,以发现相同的用户访问模式
常见的聚类算法
- 基于划分的方法:K-means算法
- 基于层次的方法:CURE算法
- 基于密度的方法:DBSCAN算法
2. k-means聚类算法
简介
-
K-means聚类算法就是基于距离的聚类算法(cluster algorithm)主要通过不断地取离种子点最近均值的算法
k-means聚类算的原理 -
一、指定需要划分的簇的个数k值;
-
二、随机地选择k个初始数据对象点作为初始的聚类中心;
-
三、计算其余的各个数据对象到这k个初始聚类中心的距离,把数据对
-
划归到距离它最近的那个中心所处在的簇类中;
-
四、调整新类并且重新计算出新类的中心。
-
五、计算聚类准则函数E,若E不满足收敛条件。重复二、三、四,
-
六、结束
距离的计算 -
我们都是以欧拉距离来计算与种子点的距离。但是,还有几种可以用于k-means的距离计算方法。闵可夫斯基距离——λ可以随意取值,可以是负数,也可以是正数,或是无穷大。
-
欧拉公式——也就是第一个公式λ=2的情况
-
曼哈顿距离——也就是第一个公式λ=1的情况
k-means距离算法的特点及应用
- 优点:
- 算法简单、快速
- 对处理大数据集,该算法是相对可伸缩的和高效率的。
- 算法尝试找出使平方误差函数值最小的k个划分。
- 缺点
- K-means聚类算法只有在簇的平均值被定义的情况下才能使用。
- 要求用户必须事先给出要生成的簇的数目k。
- 对初值敏感。
- 不适合于发现非凸面形状的簇,或者大小差别很大的簇。
- 对于“噪声”和孤立点数据敏感
k-means聚类算法的核心代码
2.1 完整代码
实战代码
import numpy as np
import matplotlib.pyplot as plt
# 加载数据
def loadDataSet(fileName):
data = np.loadtxt(fileName, delimiter='\t')
return data
# 欧氏距离计算
def distEclud(x, y):
return np.sqrt(np.sum((x - y) ** 2)) # 计算欧氏距离
# 为给定数据集构建一个包含K个随机质心的集合
def randCent(dataSet, k):
m, n = dataSet.shape
centroids = np.zeros((k, n))
for i in range(k):
index = int(np.random.uniform(0, m)) #
centroids[i, :] = dataSet[index, :]
return centroids
# k均值聚类
def KMeans(dataSet, k):
m = np.shape(dataSet)[0] # 行的数目
# 第一列存样本属于哪一簇
# 第二列存样本的到簇的中心点的误差
clusterAssment = np.mat(np.zeros((m, 2)))
clusterChange = True
# 第1步 初始化centroids
centroids = randCent(dataSet, k)
while clusterChange:
clusterChange = False
# 遍历所有的样本(行数)
for i in range(m):
minDist = 100000.0
minIndex = -1
# 遍历所有的质心
# 第2步 找出最近的质心
for j in range(k):
# 计算该样本到质心的欧式距离
distance = distEclud(centroids[j, :], dataSet[i, :])
if distance < minDist:
minDist = distance
minIndex = j
# 第 3 步:更新每一行样本所属的簇
if clusterAssment[i, 0] != minIndex:
clusterChange = True
clusterAssment[i, :] = minIndex, minDist ** 2
# 第 4 步:更新质心
for j in range(k):
pointsInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == j)[0]] # 获取簇类所有的点
centroids[j, :] = np.mean(pointsInCluster, axis=0) # 对矩阵的行求均值
print("Congratulations,cluster complete!")
return centroids, clusterAssment
def showCluster(dataSet, k, centroids, clusterAssment):
m, n = dataSet.shape
if n != 2:
print("数据不是二维的")
return 1
mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
if k > len(mark):
print("k值太大了")
return 1
# 绘制所有的样本
for i in range(m):
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])
plt.show()
dataSet = loadDataSet("test.txt")
k = 4
centroids, clusterAssment = KMeans(dataSet, k)
showCluster(dataSet, k, centroids, clusterAssment)
plt.show()
dataSet = loadDataSet("test.txt")
k = 4
centroids, clusterAssment = KMeans(dataSet, k)
showCluster(dataSet, k, centroids, clusterAssment)