机器学习之聚类算法
概念
- 聚类又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法,同时也是数据挖掘的一个重要算法。
- 聚类(Cluster)分析是由若干模式(Pattern)组成的,通常,模式是一个度量(Measurement)的向量,或者是多维空间中的一个点。
- 聚类分析以相似性为基础,在一个聚类中的模式之间比不在同一聚类中的模式之间具有更多的相似性。
算法用途
- 在商业上,聚类可以帮助市场分析人员从消费者数据库中区分出不同的消费群体来,并且概括出每一类消费者的消费模式或者说习惯。它作为数据挖掘中的一个模块,可以作为一个单独的工具以发现数据库中分布的一些深层的信息,并且概括出每一类的特点,或者把注意力放在某一个特定的类上以作进一步的分析;并且,聚类分析也可以作为数据挖掘算法中其他分析算法的一个预处理步骤。
算法分类
- 算法可以分为划分法(Partitioning Methods)、层次法(Hierarchical Methods)、基于密度的方法(density-based methods)、基于网格的方法(grid-based methods)、基于模型的方法(Model-Based Methods)。
具体方法(K-MEANS)
- 用μ1,μ2,…,μk 来表示聚类中心
- 用c(i)(i=1,…m)来存储与第 i 个样本数据x(i)最近的聚类中心的索引
- 算法分为两个步骤
1.第一个for循环,计算每个样本数据x(i)距离哪一个聚类中心近,即:对于每个样本数据x(i) ,计算其应该属于的聚类中心。用于减小c(i)引起的代价
2.第二个for循环,是聚类中心的移动,即:对于每一个聚类中心,重新计算它的中心。用于减小μk引起的代价
3.迭代的过程一定会是每一次迭代都在减小代价函数,不然便是出现了错误。
K-MEANS算法优化目标
选择聚类数:“肘部法则”
- 1.“肘部法则”,是选择聚类数目的方法。我们所要做的是改变K值,也就是聚类类别的总数。用一个聚类来运行K 均值聚类方法。这就意味着,所有的数据都会分到一个聚类里,然后计算代价函数J。
- 2.在k=2时,图形达到了一个最优的最小值。即使within-cluster的距离在2之后减少,我们还需要做更多的计算。这与收益递减律类似。因此,我们选择一个2作为最优。
聚类算法python库实现
1.数据预处理(初始化、缩放、洗牌)
2.调用库函数计算
3.展示计算结果(数据,模型)
python代码
import numpy as np # 导入numpy库
import matplotlib.pyplot as plt # 导入matplotlib.pylab库
from sklearn.cluster import KMeans # 导入sklearn.cluster库
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 原始数据集
X = [[2,5],[4,6],[3,1],[6,4],[7,2],[8,4],[2,3],[3,1],[5,7],[6,9],[12,16],[10,11],[15,19],[16,12],[11,15],[10,14],[19,11],[17,14],[16,11],[13,19]]
# 特征缩放
X -= np.mean(X,axis=0)
X /= np.std(X,axis=0,ddof=1)
# 随机生成一个聚类中心数目的列表
k = np.arange(1,11)
jarr = []
# 实现肘部法则,并画出肘部法则曲线
for i in k:
model = KMeans(n_clusters=i) # 建立模型,聚类中心的数目
model.fit(X) # 训练模型
jarr.append(model.inertia_) # 所有样本与其最近中心距离的平方和
plt.annotate(str(i),(i,model.inertia_)) # 第1个参数:加的注释的内容,第2个参数:加注释的位置的坐标
plt.title('肘部法则')
plt.plot(k,jarr)
plt.xlabel('K值')
plt.ylabel('代价函数')
plt.show()
# 根据肘部法则选取k=2时,调用库函数并训练模型
k = 2
km = KMeans(n_clusters=k)
km.fit(X)
Ci = km.predict(X)
mk = km.cluster_centers_
print('聚类中心的坐标',mk)
# 画出样本点归属的散点图
plt.scatter(X[:,0],X[:,1],c=Ci,cmap=plt.cm.Paired)
plt.scatter(mk[:,0],mk[:,1],c=['r','g'],marker='^')
for i in range(k):
plt.annotate('中心'+str(i+1),(mk[i,0],mk[i,1]),size=20)
plt.title('聚类归属点的散点图')
plt.show()
效果展示如下图: