###关于k-means的新理解

1.k-means++聚类优化算法

若给定足够的迭代次数,k-means算法就能收敛,但是有可能在局部最小值点收敛。k-means收敛局部极值的原因很可能是初始化簇类中心的距离很接近,而且算法的收敛时间也加长了,通常通过多次运行k-means聚类算法,每次运行初始化不同的簇类中心来避免这一情况。

另一种解决k-means收敛局部极值的方法是k++聚类算法,k-means++通过让簇间中心互相远离的方案来初始化簇类中心。

具体算法步骤:

1)随机选择一个样本数据作为第一个簇类中心

2)计算每一个样本到簇类中心的最小距离;

3)选择最大距离的样本点作为簇类中心;

4)重复(2)(3),直到达到簇类个数k;

5)利用这k个簇类中心作为初始化的簇类中心运行k-means算法;

2.小批量处理的k-means聚类算法

k-means聚类算法的时间复杂度随着样本数的增加而增大,若样本量达到上万时,k-means聚类算法非常耗时,因此对该数据集进行无放回随机抽样得到合适的小批量样本数据集,sklearn.cluster包提供了相应的实现方法MiniBatchKMeans。

小批量处理的k-means聚类算法在减少了收敛时间的同时,算法结果相差不大。如下结果用inertia评价k-means和MiniBatchKmeans的算法结果。

import timeimport numpy as np
import matplotlib.pyplot as pltfrom sklearn.cluster import MiniBatchKMeans, KMeans
from sklearn.metrics.pairwise import pairwise_distances_argmin
from sklearn.datasets.samples_generator import make_blobs# Generate sample data
np.random.seed(0)
# minibatch随机抽样100例样本进行训练
batch_size = 100
centers = [[1, 1], [-1, -1], [1, -1]]
n_clusters = len(centers)
# 产生3个簇类的30000个样本数据
X, labels_true = make_blobs(n_samples=30000, centers=centers, cluster_std=0.7)# k-means++算法
k_means = KMeans(init='k-means++', n_clusters=3, n_init=10)
t0 = time.time()
k_means.fit(X)
t_batch = time.time() - t0# MiniBatchKMeans算法
mbk = MiniBatchKMeans(init='k-means++', n_clusters=3, batch_size=batch_size,n_init=10, max_no_improvement=10, verbose=0)
t0 = time.time()
mbk.fit(X)
t_mini_batch = time.time() - t0# 打印k-means++运行时间和性能度量
print("k-means++_runtime= ",t_batch)
print("k_means++_metics= ",k_means.inertia_)
# 打印minibatch_k_means++运行时间和性能度量值
print("MiniBatch_k_means++_runtime= ",t_mini_batch)
print("k_means_metics= ",mbk.inertia_)#>
k-means++_runtime=  0.36002039909362793
k_means++_metics=  25164.97821695812
MiniBatch_k_means++_runtime=  0.15800929069519043
k_means_metics=  25178.611517320118

3.簇类个数k的选取

运用Calinski-Harabasz分数作为评价聚类性能的标准,分数越大,聚类性能越好,Calinski-Harabasz的含义请参考该文

代码如下:

(1)首先构建四个不同标准差的二维样本数据:

from sklearn import metrics
# 定义四个簇类中心
centers1 = [[0,0],[1, 1],[1.9, 2],[3, 3]]
# 定义每个簇类的标准差
std1 = [0.19,0.2,0.3,0.4]
# 算法可重复性
seed1 =45
# 产生4个簇类的30000个样本数据
X, labels_true = make_blobs(n_samples=30000, centers=centers1, cluster_std=std1,random_state=seed1)
plt.scatter(X[:,0],X[:,1],marker='o')
plt.show()

数据散点图如下:

(2)首先尝试性地将簇类个数设为2,即K=2,查看聚类效果图和Calinski-Harabasz分数。

# 若我们选择k=2
k_means = KMeans(init='k-means++', n_clusters=2, n_init=10,random_state=10)
y_pred = k_means.fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
scores2 = metrics.calinski_harabaz_score(X,y_pred)
print("the Calinski-Harabasz scores(k=2) is: ",scores2)

散点图效果:

Calinski-Harabasz分数:

#> the Calinski-Harabasz scores(k=2) is:  85059.39875951338

(3)以此类推将k设为2、3、4、5,最终发现设为4时Calinski-Harabasz分数,分类效果最好,因此选择簇类个数为4。

散点图效果:

#> the Calinski-Harabasz scores(k=4) is:  158961.98176157777

4. k-means聚类算法不适用的几个场景

k_means算法假设数据是各向同性的,即不同簇类的协方差是相等的,通俗讲就是样本数据落在各个方向的概率是相等的。

1)若样本数据是各向异性的,那么k-means算法的效果较差。

生成一组各向异性的样本数据:

import numpy as np
import matplotlib.pyplot as pltfrom sklearn.cluster import KMeans
from sklearn.datasets import make_blobsplt.figure(figsize=(6, 6))n_samples = 1500
random_state = 170
X, y = make_blobs(n_samples=n_samples, random_state=random_state)# 生成各项异性的数据
transformation = [[0.60834549, -0.63667341], [-0.40887718, 0.85253229]]
X_aniso = np.dot(X, transformation)plt.scatter(X_aniso[:, 0], X_aniso[:, 1], marker='.')
plt.title("Anisotropicly Distributed Blobs")plt.show()

生成样本数据的散点图效果:

根据散点图分布,我们用簇类数k=3训练样本数据:

# k =3训练数据,输出散点效果图
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_aniso)
plt.scatter(X_aniso[:, 0], X_aniso[:, 1], marker='.',c=y_pred)
plt.title("clustering scatter distributed k=3")
plt.show()

聚类效果图:

由上图可知聚类效果很差。

2)当样本数据集是非凸数据集时,k-means聚类效果较差:

首先生成非凸数据集:

# 非凸数据集
plt.figure(figsize=[6,6])
from sklearn import cluster,datasets
n_samples = 1500
noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)
plt.scatter(noisy_circles[0][:,0],noisy_circles[0][:,1],marker='.')
plt.title("non-convex datasets")
plt.show()

散点图效果:

根据散点图分布,我们用簇类数k=2训练样本数据:

# k=2训练数据
y_pred = KMeans(n_clusters=2, random_state=random_state).fit_predict(noisy_circles[0])
plt.scatter(noisy_circles[0][:, 0], noisy_circles[0][:, 1], marker='.',c=y_pred)
plt.title("non-convex k-means clustering")
plt.show()

散点图聚类效果:

由上图可知聚类效果很差。

3)当训练数据集各个簇类的标准差不相等时,k-means聚类效果不好。

# 构建不同方差的各簇类数据,标准差分别为1.0,2.5,0.5
X_varied, y_varied = make_blobs(n_samples=n_samples,cluster_std=[1.0, 2.5, 0.5],random_state=random_state)
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_varied)plt.scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
plt.title("Unequal Variance")
plt.show()

由下图可知聚类效果不好:

4)若各簇类的样本数相差比较大,聚类性能较差。

产生三个样本数分别为500,10,10的簇类:

n_samples = 1500
random_state = 170
# 产生三个簇类,每个簇类样本数是500
X, y = make_blobs(n_samples=n_samples, random_state=random_state)
# 三个簇类的样本数分别为500,100,10,查看聚类效果
X_filtered = np.vstack((X[y == 0][:500], X[y == 1][:100], X[y == 2][:5]))
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], marker='.')
plt.title("Unequal Variance")
plt.show()

散点图分布:

运用k-means对其聚类:

y_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(X_filtered)
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred,marker='.')
plt.title("Unevenly Sized Blobs")plt.show()

效果图如下:

5) 若数据维度很大时,运行时间很长,可以考虑先用pca降维。

# 产生100维的15000个样本
n_samples = 15000
random_state = 170
plt.figure(figsize=[10,6])
t0=time.time()
# 产生三个簇类,每个簇类样本数是500
X, y = make_blobs(n_samples=n_samples, n_features=100,random_state=random_state)
y_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(X)
t1 =time.time()-t0
scores1 = metrics.calinski_harabaz_score(X,y)
print("no feature dimonsion reduction scores = ",scores1)
print("no feature dimonsion reduction runtime = ",t1)

输出聚类效果和运行时间:

no feature dimonsion reduction scores =  164709.2183791984
no feature dimonsion reduction runtime =  0.5700197219848633

数据先进行PCA降维再用k-means聚类,

# 数据先pca降维,再k-means聚类
from sklearn.decomposition import PCA
pca = PCA(n_components=0.8)
s=pca.fit_transform(X)
t0=time.time()
y_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(s)
t1 =time.time()-t0
print("feature dimonsion reduction scores = ",scores1)
print("feature dimonsion reduction runtime = ",t1)

输出聚类效果和运行时间:

feature dimonsion reduction scores =  164709.2183791984
feature dimonsion reduction runtime =  0.0630037784576416

由结果对比可知,聚类效果相差无几的情况下,运行时间大大降低了。

5.k-means与knn的区别

k-means是最简单的非监督分类算法,knn是最简单的监督分类算法,初学者学完监督学习章节再去学非监督章节会感觉似曾相识,原因可能都是用距离作为评价样本间的相似度。下面列举几个区别的地方:

1)knn是监督学习方法,k-means是非监督学习方法,因此knn需要样本的标记类,k-means不需要;

2)knn不需要训练,只要找到距离测试样本最近的k个样本,根据k个样本的类别给出分类结果;k-means需要训练,训练的目的是得到每个簇类的均值向量(质心),根据质心给出测试数据的分类结果;

###关于k-means的新理解相关推荐

  1. OpenCV官方文档 理解k - means聚类

    理解k - means聚类 目标 在这一章中,我们将了解k - means聚类的概念,它是如何工作等. 理论 我们将这个处理是常用的一个例子. t恤尺寸问题 考虑一个公司要发布一个新模型的t恤. 显然 ...

  2. k均值聚类算法(K Means)及其实战案例

    算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...

  3. OpenCV的k - means聚类 -对图片进行颜色量化

    OpenCV的k - means聚类 目标 学习使用cv2.kmeans()数据聚类函数OpenCV 理解参数 输入参数 样品:它应该的np.float32数据类型,每个特性应该被放在一个单独的列. ...

  4. kmeans改进 matlab,基于距离函数的改进k―means 算法

    摘要:聚类算法在自然科学和和社会科学中都有很普遍的应用,而K-means算法是聚类算法中经典的划分方法之一.但如果数据集内相邻的簇之间离散度相差较大,或者是属性分布区间相差较大,则算法的聚类效果十分有 ...

  5. 为了联盟还是为了部落 | K means

    1. 问题 人类有个很有趣的现象,一群人在一起,过一段时间就会自发的形成一个个的小团体.好像我们很擅长寻找和自己气质接近的同类.其实不只是人类,数据也有类似情况,这就是聚类(Clustering)的意 ...

  6. 文献记录(part89)--I-k-means-+:An iterative clustering algorithm based on an enhanced k -means

    学习笔记,仅供参考,有错必究 关键词:k均值:解决方案改进:准确的k均值:迭代改进 I-k-means-+:An iterative clustering algorithm based on an ...

  7. CFS调度器的思想的新理解

    本文通过详细分析老的调度器来说明cfs的优势.总是新理解新理解的,我怎么这么没完没了啊,其实每隔一段时间我都会在工作之余再读一读linux内核源代码的关键部分,每次读都有新的理解,然后就第一时间将心得 ...

  8. K means 图片压缩

    k-means的基本原理较为清晰,这里不多赘述,本次博客主要通过基础的k means算法进行图像的压缩处理. 原理分析 在彩色图像中,每个像素的大小为3字节(RGB),可以表示的颜色总数为256 * ...

  9. ccxt k线数据_机器学习系列:深度探秘K线结构新维度

    标星★公众号,第一时间获取最新研究 来源:光大证券金工团队独家授权 作者:胡骥聪 近期原创文章: ♥ 基于无监督学习的期权定价异常检测(代码+数据) ♥ 5种机器学习算法在预测股价的应用(代码+数据) ...

最新文章

  1. Servlet 工作原理解析
  2. js实现反恐精英+曲线图+饼状图
  3. 模拟撞击_正确看待小行星威胁!NASA模拟8年后300米小行星撞击地球试验
  4. 如何通过JavaScript动态加载js
  5. ue4材质节点怎么用_济南装修:阳台储物柜用什么材质好?怎么保养阳台储物柜?...
  6. 资源 | Deeplearning.ai课程与笔记汇总
  7. javascript --- 从数组中,找出比给定元素大一丁点的元素
  8. window.open打开页面并传值,window. location.search遍历获取到的请求链接中的所有参数
  9. 利用RazorSQL如何创建SSH密钥
  10. 3、Keras中的顺序模型Sequential和函数式模型Model
  11. matlab控制信号发生器,Matlab 跳频信号发生器
  12. wav格式怎么转换成mp3格式
  13. 中柏平板u盘启动_中柏笔记本一键U盘重装系统教程图解
  14. git commit 提交信息写错,怎么更改?
  15. string与int之间转换
  16. APP推广渠道之SEM渠道相关知识科普
  17. python简单抽奖系统_python实现的简单抽奖系统实例
  18. YTU 3166: 共享单车
  19. 前端大文件上传断点续传解决方案
  20. android无法加载sd卡上的字体,[Android]AnkiDroid 0.6 版暂时不支持(某些)音标字体的显示,附解决办法 | 古意人...

热门文章

  1. Acxiom 安客诚 是什么?
  2. 关于对我Blog一些文章的说明
  3. 设计模式之---享元模式(Flyweight Pattern)
  4. window服务器间传输文件
  5. onbeforepaste
  6. 【Android Camera1】Camera1 对焦(一) UI坐标系和相机坐标系
  7. 掌财社骑士:什么是短线牛股?怎么抓短线牛股?
  8. Registry的安装和使用
  9. 阿里春招笔试2020.3.27(贪心/差分/概率)
  10. 张敏计算机专业,张敏 - 计算机与信息科学学院 - Powered by 西南大学