0 前言
K-Means是聚类算法的一种,通过距离来判断数据点间的相似度并据此对数据进行聚类。
1 聚类算法
方法名称 | 参数 | 可伸缩性 | 用例 | 几何形状(使用的指标) |
---|---|---|---|---|
number of clusters | Very large , medium with MiniBatch code | General-purpose, even cluster size, flat geometry, not too many clusters | Distances between points | |
damping, sample preference | Not scalable with n_samples | Many clusters, uneven cluster size, non-flat geometry | Graph distance (e.g. nearest-neighbor graph) | |
bandwidth | Not scalable with | Many clusters, uneven cluster size, non-flat geometry | Distances between points | |
number of clusters | Medium , small | Few clusters, even cluster size, non-flat geometry | Graph distance (e.g. nearest-neighbor graph) | |
number of clusters or distance threshold | Large and | Many clusters, possibly connectivity constraints | Distances between points | |
number of clusters or distance threshold, linkage type, distance | Large and | Many clusters, possibly connectivity constraints, non Euclidean distances | Any pairwise distance | |
neighborhood size | Very large , medium | Non-flat geometry, uneven cluster sizes | Distances between nearest points | |
minimum cluster membership | Very large , large | Non-flat geometry, uneven cluster sizes, variable cluster density | Distances between points | |
many | Not scalable | Flat geometry, good for density estimation | Mahalanobis distances to centers | |
branching factor, threshold, optional global clusterer. | Large and | Large dataset, outlier removal, data reduction. | Euclidean distance between points |
2 先导知识
2.0 理论知识
K-MEANS算法是输入聚类个数k以及包含 n个数据对象的数据库,输出满足方差最小标准k个聚类的一种算法。k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。
而作为分类依据的聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算得到的。
2.1 算法步骤
(1) 从 n个数据对象任意选择 k 个对象作为初始聚类中心;
(2) 根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;
(3) 重新计算每个(有变化)聚类的均值(中心对象);
(4) 计算标准测度函数,当满足一定条件,如函数收敛时,则算法终止;如果条件不满足则回到步骤(2)。
优缺点
优点:算法简单易懂,易于实现(MATLAB与Python都有相应的工具与库)
缺点:存在收敛于局部最小值的可能;在大规模数据收敛慢
2.2 库
首先,K-means在sklearn.cluster中,我们用到K-means聚类时,调用格式:
from sklearn.cluster import KMeans
标准的库函数定义及其参数解释:
class sklearn.cluster.KMeans(n_clusters=8, init=’k-means++’, n_init=10, max_iter=300, tol=0.0001, precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm=’auto’)
输入
1.n_clusters : int, optional, default: 8,表示要聚类生成的簇的数量,也就是聚类中心的数量。要求输入为整数型,默认值为8;
2.init : {‘k-means++’, ‘random’ or an ndarray},表示对进行聚类的数据初始化的方法,默认的方法是’k-means++’。初始化的方法有三种:k-means++,random,或者是一个数组。k-means++能智能的选择初始聚类中心进行k均值聚类,加快收敛速度;random则是从数据中随机的选择k个观测值作为初始的聚类中心;也可以传递给init一个数组作为初始化的聚类中心,则这个数组的结构应该是(n_clusters, n_features),后附代码则是利用数组进行初始化。
3.n_init : int, default: 10,表示K-means算法选择聚类中心的次数,默认值为10。算法最终返回的是聚类中心最好的一次结果,也就是时间最短的一次结果;
4.max_iter : int, default: 300,表示每次运行K-means算法的最大迭代次数,默认值为300;
5.tol : float, default: 1e-4 ,表示容忍度,相当于是迭代终止的精度要求或者可以允许的误差,当满足这个精度则聚类收敛,认为寻找到最优解,此时可以停止迭代,默认值为0.0001;
6.precompute_distances : {‘auto’, True, False},表示预先计算距离,在空间和时间上作出权衡。相当于是否需要判断“用空间来换取时间”,即如果选择true处理时间会更快,但是会占用更多的内存,默认值为‘auto’;‘auto’指如果n_samples * n_clusters > 12亿时,就不预先计算距离。这样就相当于使用双精度的每个作业大约需要100MB的内存;‘True’指总是预先计算距离;‘False’指不预先计算距离;
7.verbose : int, default 0,是否输出详细信息,默认值为0;
8.random_state : int, RandomState instance or None (default),确定聚类中心初始化的随机数生成,使用一个整型数使得随机性具有确定性,默认值为None;
9.copy_x : boolean, optional,bool 在scikit-learn 很多接口中都会有这个参数的,就是是否对输入数据继续copy 操作,以便不修改用户的输入数据,默认值为True。True时,是不修改原始数据,确保X是C-contiguous,聚类后不修改原始数据;False时,则修改原始数据,在函数返回之前将修改后的放回X,但通过减去再加上数据均值,可能会引入较小的数值差异,在这种情况下也不能保证数据是C-contiguous,可能会使速度明显的下降;
10.n_jobs : int or None, optional (default=None),使用进程的数量,与电脑CPU有关。默认值为None;
11.algorithm : “auto”, “full” or “elkan”, default=“auto”,K-means算法所用到的“full”指经典的EM-style算法;“elkan”通过使用三角不等式,优点是处理更加高效,但不支持稀疏的数据;“auto”则在数据密集时,选择“elkan”,在数据稀疏时,选择“full”。
输出
1.cluster_centers_:返回聚类中心的坐标;
2.labels_:每个点的标签;
3.inertia_:样本到聚类中心的平方和,聚类准则的总和;
4.n_iter_:迭代运行的次数;
3 代码实例
3.0 数据解释
本次K-means聚类的数据利用杨老师的湖北省某地的土壤属性数据,我选择了其中的三类数据,分别命名为‘PH’、‘S’、'N';导入Python的是一个n*4的数据,第一列为ID,即序号表明不同的点序列。
'''
@Author: your name
@Date: 2020-04-07 10:52:14
@LastEditTime: 2020-04-07 13:51:27
@LastEditors: Please set LastEditors
@Description: In User Settings Edit
@FilePath: \learn\kmeans.py
'''
import xlrd
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# 从Excel中读取数据存入数组
rawData = xlrd.open_workbook('kmeans.xlsx')
table = rawData.sheets()[0]
data = []
for i in range(table.nrows):
if i == 0:
continue
else:
data.append(table.row_values(i)[1:])
featureList = ['PH', 'S', 'N']
mdl = pd.DataFrame.from_records(data, columns=featureList)
# 聚类
mdl_new = np.array(mdl[['PH', 'S', 'N']])# 将其转化为数组
seed = 9# 设置随机数
clf = KMeans(n_clusters=3, random_state=seed)# 构造k-means聚类器
clf.fit(mdl_new)# 拟合模型
print(clf.cluster_centers_) # 以数组形式查看KMeans聚类后的质心点,即聚类中心。
mdl['label'] = clf.labels_ # 对原数据表进行类别标记
c = mdl['label'].value_counts()
print(mdl.values)# 以数组形式打印结果
#图形化展示
label_pred = clf.labels_ #获取聚类标签
centroids = clf.cluster_centers_ #获取聚类中心
inertia = clf.inertia_ # 获取聚类准则的总和
mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
# 这里'or'代表中的'o'代表画圈,'r'代表颜色为红色,后面的依次类推
color = 0
j = 0
for i in label_pred:
plt.plot([mdl_new[j:j+1,0]], [mdl_new[j:j+1,1]],
mark[i], markersize = 5)
j +=1
plt.show()# 画出聚类结果简易图
注:K-means算法实现需要导入pandas、numpy、sklearn以及pyplot等库函数,需要在学习过程中不断更新自己的知识储备。当然了,K-means只是我们接触机器学习的第一个例子,相关的资料也很多但是还是需要自己阅读Python文档之后再进行参考。
结果分析
ns.py
[[ 7.52222222 16.38 0.93444444]
[ 5.92857143 26.94571429 1.62714286]
[ 7.825 9.3825 0.6975 ]]
[[ 8. 4.89 0.48 2. ]
[ 7.8 10.31 0.72 2. ]
[ 7.6 10.85 0.78 2. ]
[ 7.7 17.64 1.05 0. ]
[ 7.9 11.48 0.81 2. ]
[ 7.2 17.27 1.04 0. ]
[ 7.2 16.95 0.98 0. ]
[ 7.8 15.45 0.88 0. ]
[ 7.3 17.76 0.99 0. ]
[ 7.1 14.31 0.89 0. ]
[ 7.9 17.71 0.96 0. ]
[ 7.8 13.58 0.74 0. ]
[ 7.7 16.75 0.88 0. ]
[ 6. 26.45 1.62 1. ]
[ 6. 27.59 1.73 1. ]
[ 5.9 23.12 1.41 1. ]
[ 6. 26.9 1.65 1. ]
[ 6.3 26.29 1.62 1. ]
[ 5.6 33.39 1.93 1. ]
[ 5.7 24.88 1.43 1. ]]
输出结果主要为两部分:第一部分为每个聚类簇的质点;第二部分为四列,前三列为各个采样点的三类属性值,第四列是聚类的结果(0,1,2)表示不同的类别。
注:由于数据是三维的,因为博主只是用二维作图直观化展示,并不严格。
参考资料:Learn Python、sklearn