10 利用K-均值聚类算法对未标注数据分组
10.1 K-均值聚类算法
- 算法特点
- 优点:容易实现和理解
- 缺点:可能收敛到局部最小,且在大规模数据集上收敛较慢
- 适用数据:数值型数据
- 一般流程:
- 收集数据
- 准备数据:需要数值型数据计算举例,标称型数据需要映射为二值型数据。
- 分析数据
- 训练算法:无监督学习不需要训练
- 测试算法:可使用量化误差指标如误差平方和来评价结果
- 使用算法:通常情况下,簇质心可以代表整个簇的数据来做出决策。
- 算法步骤:
- 先初始化k个簇质心
- 遍历每个数据点,并计算每个数据点与每个簇质心的距离,并把其分到距离最小的质心的簇中。用每个簇中点的均值作为每个簇最新质心。
- 重复以上过程,直到所有的数据点所属的簇质心都不再发生变化。
- 距离计算函数:欧式距离
10.2 使用后处理来提高聚类性能
一般情况下,使用K-均值算法可能收敛于局部最优而非全局最优,此时分类结果可能不够理想,需要对结果进行再处理。
衡量指标:SSE,误差平方和,用于衡量个各簇中的数据点与质心的距离。
10.3 二分K-均值算法
二分k-均值算法可克服收敛于局部最小。初始化1个簇,并对每个簇逐步二分,直到簇数量等于用户指定数量。
- 步骤
- 把所有数据归类为1个簇,簇质心为数据的均值。
- 对所有的簇,尝试用K-均值算法一分为二。计算二分前的SSE1和二分后总的SSE2,diffSSE = SSE1 - SSE2,计算选择diffSSE最大的簇进行二分。(也可直接用SSE1最大的簇进行二分)
- 重复以上过程,直到簇数量等于目标簇数k
算法实现
def loadDataSet(fileName):
dataMat = []
with open(fileName, "rb") as fr:
for line in fr.readlines():
curLine = line.strip().split("\t")
fltLine = map(float, curLine)
dataMat.append(fltLine)
return dataMat
def distEclud(vecA, vecB):
"""
计算两个向量的欧氏距离
"""
return np.sqrt(np.sum(np.power(vecA - vecB, 2)))
def randCent(dataSet, k):
"""
为数据集构建一个包含k个随机质心的集合
"""
n = np.shape(dataSet)[1]
centroids = np.mat(np.zeros((k, n)))
for j in range(n):
minJ = min(dataSet[:, j])
rangeJ = float(max(dataSet[:, j]) - minJ)
centroids[:, j] = minJ + rangeJ * np.random.rand(k, 1) # 最小值+最大最小值范围*0-1随机数, 使随机簇心在最大和最小值之间
return centroids
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = np.shape(dataSet)[0]
clusterAssment = np.mat(np.zeros((m, 2))) # 簇分配结果矩阵,两列分别记录簇索引值和存储误差
centroids = createCent(dataSet, k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m):
minDist = np.inf
minIndex = -1
for j in range(k):
distJI = distMeas(centroids[j, :], dataSet[i, :])
if distJI < minDist:
minDist = distJI
minIndex = j
if clusterAssment[i, 0] != minIndex:
clusterChanged = True # 当该点的簇分配发生变化时,需要重新计算簇心并再次遍历
clusterAssment[i, :] = minIndex, minDist**2
print centroids
for cent in range(k):
ptsInClust = dataSet[np.nonzero(clusterAssment[:, 0].A == cent)[0]]
centroids[cent, :] = np.mean(ptsInClust, axis=0) # 更新质心的值为簇均值
return centroids, clusterAssment
# 测试算法
dataMat = np.mat(loadDataSet("machinelearninginaction/Ch10/testSet.txt"))
myCentroids, clustAssing = kMeans(dataMat, 4)
# 可视化
markerList = ["*", "^", "o", "s"]
for i in range(4):
plotData = dataMat[np.nonzero(clustAssing[:, 0].A == i)[0]]
plt.scatter(plotData[:, 0].A, plotData[:, 1].A, marker=markerList[i])
plt.scatter(myCentroids[:, 0].A, myCentroids[:, 1].A, marker="+")
10.4 示例:对地图上的点进行聚类
(Unfinished)
11 使用Apriori算法进行关联分析
- 关联分析:也称关联规则学习,指从大规模数据集中寻找物品间的隐含关系。
- Apriori算法:
- 优点:易编码实现
- 缺点:效率较低,在大数据集上可能较慢
- 适用数据:数值型或标称型数据
11.1 关联分析
- 频繁项集:经常一起出现的集合
- 关联规则:两种物品之间可能存在的强关系
- 支持度:数据集中包含该项集的记录所占的比例
- 置信度(可信度):某关联规则的强度的衡量指标。如{A}→{B}的置信度为: 支 持 度 A , B 支 持