一、聚类分析
- 是无监督学习算法中最常用的一类
- 聚类是将数据分类到不同的类或者簇这样的一个过程,所以同一个簇中的对象有很大的相似性,而不同簇间的对象有很大的相异性
- 聚类与分类的不同在于,聚类所要求的划分的类是未知的。
二、常见的聚类算法
- K-Means聚类
- 层次聚类
- DBSCAN
三、K-均值聚类算法
1.定义
是一种迭代求解的聚类分析算法
2.工作流程
- 随机确定K个初始点作为质心,K为用户给定值
- 为每个点找距其最近的质心,并将这些点分别分配给该质心所对应的的簇或类
- 每个簇的质心更新为该簇所有点的平均值
3.伪代码
创建k个点作为起始质心(经常是随机选择)
当任意一个点的簇分配结果发生改变时
对数据集中的每个数据点
对每个质心
计算质心与数据点之间的距离
将数据点分配到距其最近的簇
对每一个簇,计算簇中所有点的均值并将均值作为质心
4.Python实现
引包:
import pandas as pd
import numpy as np
读取数据
数据地址:
链接:https://pan.baidu.com/s/1vtmvoTb6g2ZUQOzjTFjkRQ
提取码:zy1m
dataSet = pd.read_csv('iris.txt', header = None)
计算距离函数
计算距离的方法有很多,这里使用的是最简单的欧氏距离
def calDist(arrA, arrB):
"""
计算欧式距离,返回一个点到各个质心的距离
arrA --> ndarray
arrB --> ndarray
return --> ndarray
"""
d = arrA - arrB
s = (np.sum(np.power(d, 2), axis=1))
dist = np.sqrt(s.tolist())
return dist
选取随机质心函数
虽然可以随机选取质心,但如果选取不在点所在区域的质心,会加大计算量,并使结果误差较大。所以再好从每列数值范围内选取质心。
def randCent(dataSet, k):
"""
"""
n = dataSet.shape[1]
min = dataSet.iloc[:, :n - 1].min()
max = dataSet.iloc[:, :n - 1].max()
randCent = np.random.uniform(min, max, (k, n - 1))
return randCent
KMeans聚类算法
本质上就是一个不断计算距离并迭代质心的过程。其中:
centroids
def KMeans(dataSet,k,distMeas = calDist,createCent = randCent):
"""
:param dataSet: 数据集
:param k: 指定质心个数
:param distMeas : 欧氏距离计算函数
:param corids: 随机质心选取函数
:return: centroids--> 质心 ndarray
result_set --> 分类结果 DataFrame
"""
m,n = dataSet.shape
centroids = createCent(dataSet,k)
clusterAssment = np.zeros((m,3)) # 创建一个容器,分别存放距离,该次所属质心,上一次所属质心
clusterAssment[:,0] = np.inf
clusterAssment[:,1:3] = -1
result_set = pd.concat([dataSet,pd.DataFrame(clusterAssment)],axis=1,ignore_index=True)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m):
dist = distMeas(dataSet.iloc[i,:n-1].values,centroids)
result_set.iloc[i,n] = dist.min()
result_set.iloc[i,n+1] = np.where(dist == dist.min())[0]
clusterChanged = not(result_set.iloc[:,-1] == result_set.iloc[:,-2]).all() # 终止条件:每一个点所属质心不再改变
if clusterChanged:
cent_df = result_set.groupby(n+1).mean() # 使用平均值代替质心
centroids = cent_df.iloc[:,:n-1].values
result_set.iloc[:,-1] = result_set.iloc[:,-2] # 将此次质心分类存储,与下一次迭代对比
return centroids,result_set
5.使用场景
K-Means聚类算法:
- 优点:容易实现
- 缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢
- 使用数据类型:数值型数据
参考资料:《机器学习实战》-- Peter Harrington
菊安酱的机器学习