聚类与分类的区别
分类: 类别是已知的,通过对已知分类的数据进行训练和学习,找到不同类的特征再对未分类的数据进行分类,属于监督学习。
聚类: 事先不知道数据会分为几类,通过聚类分析将数据聚合成几个群体。聚类不需要对数据进行训练和学习。属于无监督学习。
数据输入有标签则为监督学习,否则为无监督学习
k-means 聚类怎么算
- 首先输入 k 的值,即希望通过聚类得到 k 个分组;
- 从数据集中随机选取 k 个数据点作为初始质心
- 对数据中每一个点计算与每一个质心的距离,离哪个质心近,就分为哪一类
- 基于当前分好的类,重新计算类中的所有向量的平均值,确定新的质心
- 重复3、4步
- 直到新的质心与老的质心的距离小于某一个设定的阈值,可以认为达到预期,算法终止。
具体步骤如下图:
k-means 聚类 Python 实现
import numpy as np
from sklearn.cluster import KMeans
data = np.random.rand(100, 3) #生成一个随机数据,样本大小为100, 特征数为3
#假如我要构造一个聚类数为3的聚类器
estimator = KMeans(n_clusters=3)#构造聚类器
estimator.fit(data)#聚类
label_pred = estimator.labels_ #获取聚类标签
centroids = estimator.cluster_centers_ #获取聚类中心
inertia = estimator.inertia_ # 获取聚类准则的总和
主函数 KMeans 参数解释
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=1,
algorithm='auto'
)
n_clusters
:簇的个数,即你想聚成几类init
: 初始簇中心的获取方法n_init
: 获取初始簇中心的更迭次数,为了弥补初始质心的影响,算法默认会初始10次质心,实现算法,然后返回最好的结果。max_iter
: 最大迭代次数(因为kmeans算法的实现需要迭代)tol
: 容忍度,即kmeans运行准则收敛的条件precompute_distances
:是否需要提前计算距离,这个参数会在空间和时间之间做权衡,如果是True 会把整个距离矩阵都放到内存中,auto 会默认在数据样本大于featurs*samples 的数量大于12e6 的时候False,False 时核心实现的方法是利用Cpython 来实现的verbose
: 冗长模式(不太懂是啥意思,反正一般不去改默认值)random_state
: 随机生成簇中心的状态条件。copy_x
: 对是否修改数据的一个标记,如果True,即复制了就不会修改数据。bool 在scikit-learn 很多接口中都会有这个参数的,就是是否对输入数据继续copy 操作,以便不修改用户的输入数据。这个要理解Python 的内存机制才会比较清楚。n_jobs
: 并行设置algorithm
: kmeans的实现算法,有:auto
,full
,elkan
, 其中full
表示用EM方式实现
具体 Python 实现
# coding=utf-8
"""
Created on 2019/10/9 16:31
@author: EwdAger
"""
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
data = pd.read_csv(r"F:\MachineLearning\Kmeans\data\testSet.txt", sep='\t',
header=0, dtype=str, na_filter=False).astype(np.float)
k = 4
clt = KMeans(n_clusters=k)
clt.fit(data)
cents = clt.cluster_centers_ # 获取聚类中心
labels = clt.labels_ # 获取聚类标签
colors = ['b', 'g', 'r', 'k', 'c', 'm', 'y', '#e24fff', '#524C90', '#845868']
# 画图
for i in range(k):
# 获取i组数据的index
index = np.nonzero(labels == i)[0]
x0 = data.iloc[data.index.isin(index), 0].tolist()
x1 = data.iloc[data.index.isin(index), 1].tolist()
y_i = i
# 给第i组数据涂上颜色,进行分组
for j in range(len(x0)):
plt.text(x0[j], x1[j], str(y_i), color=colors[i], fontdict={'weight': 'bold', 'size': 6})
# 绘制该组质心
plt.scatter(cents[i, 0], cents[i, 1], marker='x', color=colors[i], linewidths=7)
plt.axis([-7, 7, -7, 7])
plt.show()
结果如下: