2019-10-16 机器学习-聚类算法-K-means(K-均值聚类)-原理解析-代码实现(Scikit-learn)

今天我们来看一个非常常见和使用的无监督机器学习算法——K-均值聚类(K-means)

首先我们先了解一下这个算法的大致背景:

首先要知道什么是聚类

聚是一个将数据集中在某些方面相似的数据成员进行分类组织的过程,聚类就是一种发现这种内在结构的技术,聚类技术经常被称为无监督学习。

通俗的说,就是比如我们去海南种水稻,水稻田里面有各种各样的水稻,每株水稻的高低颜色还有其他很多特征都不一样,我们更具这些特征对水稻进行分类,相似的聚为一类。

水稻之间表现有差异

K-均值聚类的定义

给定一个数据点集合和需要的聚类数目k,k由用户指定,k均值算法根据某个距离函数反复把数据分入k个聚类中

具体什么含义呢?就是我把每个样本点的数据搜集好,形成了一个数据集,然后我人为地定义一个K,就是我想聚成K类,那么K-means算法就会根据我定义的K进行反复迭代和计算,最后,我的所有样本就会被分成K类

图片来自网络

K-means算法的实现

摘自百度百科,我觉的百度百科已经说得很清楚了

先随机选取K个对象作为初始的聚类中心。然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是以下任何一个:
Step 1 没有(或最小数目)对象被重新分配给不同的聚类
Step 2 没有(或最小数目)聚类中心再发生变化
Step 3 误差平方和局部最小。

伪代码

选择k个点作为初始质心。
repeat 将每个点指派到最近的质心,形成k个簇 重新计算每个簇的质心
until 质心不发生变化

既然是学习最简单的K-means,就先不讲太多的复杂内容,直接上代码来实战一下。

Scikit-learn - K-means 实战

首先我先定义一些数据,假设我在海南种水稻的时候,测量的水稻的株高和剑叶长(数据纯属乱扯的哈)。

from sklearn.cluster import KMeans
import numpy as np
import pandas  as pd
import matplotlib.pyplot as plt
X = np.array([[1, 2], [1, 4], [1, 1],
              [6, 2], [2, 3], [4, 2],
              [8, 1], [4, 5], [5, 3],
              [3, 0], [5, 0], [6, 4],
              [4, 9], [6, 4], [3, 6],
              [5, 4], [9, 7], [2, 4],
              [6, 2], [4, 5], [8, 3]])
X

我们将数据输入这个矩阵中

举个例子

然后我们大致看一下数据的情况

from sklearn.cluster import KMeans
import numpy as np
import pandas  as pd
import matplotlib.pyplot as plt
X = np.array([[1, 2], [1, 4], [1, 1],
              [6, 2], [2, 3], [4, 2],
              [8, 1], [4, 5], [5, 3],
              [3, 0], [5, 0], [6, 4],
              [4, 9], [6, 4], [3, 6],
              [5, 4], [9, 7], [2, 4],
              [6, 2], [4, 5], [8, 3]])
plt.scatter(X[:, 0], X[:, 1], c = "red", marker='o', label='see')   
plt.show()
这个是个二维的数据

然后直接用scikit的函数训练,这里我们可以设置 K, 我先设置成 K=2 的情况

from sklearn.cluster import KMeans
import numpy as np
import pandas  as pd
import matplotlib.pyplot as plt
X = np.array([[1, 2], [1, 4], [1, 1],
              [6, 2], [2, 3], [4, 2],
              [8, 1], [4, 5], [5, 3],
              [3, 0], [5, 0], [6, 4],
              [4, 9], [6, 4], [3, 6],
              [5, 4], [9, 7], [2, 4],
              [6, 2], [4, 5], [8, 3]])

rice_cluster = KMeans(n_clusters=2)  #设置一个你想分的类别,定义一个聚类器

rice_cluster.fit(X) # 使用这个数据进行训练

rice_cluster.labels_  # 我们可以看到每个样本点的聚类标签

已经给出了标签

我们画图来看一下结果

from sklearn.cluster import KMeans
import numpy as np
import pandas  as pd
import matplotlib.pyplot as plt
X = np.array([[1, 2], [1, 4], [1, 1],
              [6, 2], [2, 3], [4, 2],
              [8, 1], [4, 5], [5, 3],
              [3, 0], [5, 0], [6, 4],
              [4, 9], [6, 4], [3, 6],
              [5, 4], [9, 7], [2, 4],
              [6, 2], [4, 5], [8, 3]])

rice_cluster = KMeans(n_clusters=2)  #设置一个你想分的类别,定义一个聚类器

rice_cluster.fit(X) # 使用这个数据进行训练

label = rice_cluster.labels_
x0 = X[label == 0]
x1 = X[label == 1]

plt.scatter(x0[:, 0], x0[:, 1], c = "red", marker='o', label='label0')  
plt.scatter(x1[:, 0], x1[:, 1], c = "blue", marker='*', label='label1')   
plt.show()  
分成了2类

使用轮子的好处就是你主要调参就行了,接下来我们调整成3类试试看

from sklearn.cluster import KMeans
import numpy as np
import pandas  as pd
import matplotlib.pyplot as plt
X = np.array([[1, 2], [1, 4], [1, 1],
              [6, 2], [2, 3], [4, 2],
              [8, 1], [4, 5], [5, 3],
              [3, 0], [5, 0], [6, 4],
              [4, 9], [6, 4], [3, 6],
              [5, 4], [9, 7], [2, 4],
              [6, 2], [4, 5], [8, 3]])

rice_cluster = KMeans(n_clusters=3)  #设置一个你想分的类别,定义一个聚类器

rice_cluster.fit(X) # 使用这个数据进行训练

label = rice_cluster.labels_
x0 = X[label == 0]
x1 = X[label == 1]
x2 = X[label == 2]

plt.scatter(x0[:, 0], x0[:, 1], c = "red", marker='o', label='label0')  
plt.scatter(x1[:, 0], x1[:, 1], c = "blue", marker='*', label='label1')   
plt.scatter(x2[:, 0], x2[:, 1], c = "green", marker='+', label='label2')   
plt.show()  
3类的结果

用起来不是很难,关键是我们要懂其内在的原理,同时清楚自己要解决的问题是什么。

评价模型好坏

我们先来看看模型的中心点

rice_cluster.cluster_centers_
这个就是中心点的值

然后可以用已经训练好的模型,去预测新的值

rice_cluster.predict([[1, 1], [5, 3],[5, 6]])
模型会告诉你属于哪一类

还有一个评价体系,评价模型好坏,结果与1越接近,样本聚类越合理

from sklearn import metrics
score=metrics.silhouette_score(X,label)
score
score值

K-means 优缺点介绍

优点:简单 快捷 如果簇是密集的,分类效果特别好

缺点:处理符号属性的数据不适用、必须实现给出K值、对初始值有一定的要求,初始值设定不当,聚类结果可能不同、如果有极端值,会影响平均值

K-means 算法升级

这里就不做多的介绍,可以自行搜索scikit-learn聚类
里面有详细的介绍,我们要根据自己实际的数据情况选择相应的聚类方法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容