`
vinking934296
  • 浏览: 106825 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

python sklearn-06:聚类-k-means

阅读更多

聚类是用于找出不带标签数据的相似性的算法。

 译文链接:https://muxuezi.github.io/posts/6-clustering-with-k-means.html

1.K-Means算法

由于具有出色的速度和良好的可扩展性,K-Means聚类算法算得上是最著名的聚类方法。K-Means算

法是一个重复移动类中心点的过程,把类的中心点,也称重心(centroids),移动到其包含成员的平

均位置,然后重新划分其内部成员。 是算法计算出的超参数,表示类的数量;K-Means可以自动分

配样本到不同的类,但是不能决定究竟要分几个类。 必须是一个比训练集样本数小的正整数。

有时,类的数量是由问题内容指定的。也有一些问题没有指定聚类的数量,最优的聚类

数量是不确定的。后面我们会介绍一种启发式方法来估计最优聚类数量,称为肘部法则(Elbow

Method)。

K-Means的参数是类的重心位置和其内部观测值的位置。与广义线性模型和决策树类似,K-Means参

数的最优解也是以成本函数最小化为目标。K-Means成本函数公式如下:



 

是第 uk个类的重心位置。成本函数是各个类畸变程度(distortions)之和。每个类的畸变程度等于

该类重心与其内部成员位置距离的平方和。若类内部的成员彼此间越紧凑则类的畸变程度越小,反

之,若类内部的成员彼此间越分散则类的畸变程度越大。求解成本函数最小化的参数就是一个重复配

置每个类包含的观测值,并不断移动类重心的过程。首先,类的重心是随机确定的位置。实际上,重

心位置等于随机选择的观测值的位置。每次迭代的时候,K-Means会把观测值分配到离它们最近的

类,然后把重心移动到该类全部成员位置的平均值那里。

 

应用例子:

import numpy as np
from sklearn.cluster import KMeans
from sklearn import metrics
plt.figure(figsize=(8, 10))
plt.subplot(3, 2, 1)
x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 7, 9])
x2 = np.array([1, 3, 2, 2, 8, 6, 7, 6, 7, 1, 2, 1, 1, 3])
X = np.array(list(zip(x1, x2))).reshape(len(x1), 2)
plt.xlim([0, 10])
plt.ylim([0, 10])
plt.title('样本',fontproperties=font)
plt.scatter(x1, x2)


 
 

#接上面
plt.scatter(x1, x2)
colors = ['b', 'g', 'r']
markers = ['o', 's', 'D']
t=3
kmeans_model = KMeans(n_clusters=3).fit(X)
for i, l in enumerate(kmeans_model.labels_):
    plt.plot(x1[i], x2[i], color=colors[l],marker=markers[l],ls='None')
    plt.xlim([0, 10])
    plt.ylim([0, 10])
    plt.title('K = %s' %(t),fontproperties=font)

 

 

局部最优解:

K-Means的初始重心位置是随机选择的。有时,如果运气不好,随机选择的重心会导致K-Means陷入局部最优解。这些类可能没有实际意义,为了避免局部最优解,K-Means通常初始时要重复运行十几次甚至上百次。每次重复时,它会随机的从不同的位置开始初始化。最后把最小的成本函数对应的重心位置作为初始位位置。

 

 

2.K值确定:

肘部法则:

如果问题中没有指定 的值,可以通过肘部法则这一技术来估计聚类数量。肘部法则会把不同 值的

成本函数值画出来。随着 值的增大,平均畸变程度会减小;每个类包含的样本数会减少,于是样本

离其重心会更近。但是,随着 值继续增大,平均畸变程度的改善效果会不断减低。 值增大过程

中,畸变程度的改善效果下降幅度最大的位置对应的 值就是肘部。

 

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font = FontProperties(fname=r"C:\Windows\Fonts\msyh.ttc", size=10)

import numpy as np
cluster1 = np.random.uniform(0.5, 1.5, (2, 10))
cluster2 = np.random.uniform(3.5, 4.5, (2, 10))
X = np.hstack((cluster1, cluster2)).T
plt.figure()
plt.axis([0, 5, 0, 5])
plt.grid(True)
plt.plot(X[:,0],X[:,1],'k.');

 

 

计算 K值从1到10对应的平均畸变程度:

from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
K = range(1, 10)
meandistortions = []
for k in K:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X)
    meandistortions.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('平均畸变程度',fontproperties=font)
plt.title('用肘部法则来确定最佳的K值',fontproperties=font);

 

 从图中可以看出K 值从1到2时,平均畸变程度变化最大。超过2以后,平均畸变程度变化显著降

低。因此肘部就是K=2 。

 

例子2:

import numpy as np
x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 7, 9])
x2 = np.array([1, 3, 2, 2, 8, 6, 7, 6, 7, 1, 2, 1, 1, 3])
X = np.array(list(zip(x1, x2))).reshape(len(x1), 2)
plt.figure()
plt.axis([0, 10, 0, 10])
plt.grid(True)
plt.plot(X[:,0],X[:,1],'k.');



 

from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
K = range(1, 10)
meandistortions = []
for k in K:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X)
    meandistortions.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('平均畸变程度',fontproperties=font)
plt.title('用肘部法则来确定最佳的K值',fontproperties=font);

 

 从图中可以看出,K值从1到3时,平均畸变程度变化最大。超过3以后,平均畸变程度变化显著降

低。因此肘部就是K=3。

 

3.聚类效果评估

K-Means是一种非监督学习,没有标签和其他信息来比较聚类结果。但是,还是有

一些指标可以评估算法的性能。已经介绍过类的畸变程度的度量方法。下面将介绍另一种聚类

算法效果评估方法称为轮廓系数(Silhouette Coefficient)。轮廓系数是类的密集与分散程度的评价

指标。它会随着类的规模增大而增大。彼此相距很远,本身很密集的类,其轮廓系数较大,彼此集

中,本身很大的类,其轮廓系数较小。轮廓系数是通过所有样本计算出来的,计算每个样本分数的均

值,计算公式如下:



 

a是每一个类中样本彼此距离的均值, b是一个类中样本与其最近的那个类的所有样本的距离的均

值。下面的例子运行四次K-Means,从一个数据集中分别创建2,3,4,8个类,然后分别计算它们

的轮廓系数。

import numpy as np
from sklearn.cluster import KMeans
from sklearn import metrics
plt.figure(figsize=(8, 10))
plt.subplot(3, 2, 1)
x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 7, 9])
x2 = np.array([1, 3, 2, 2, 8, 6, 7, 6, 7, 1, 2, 1, 1, 3])
X = np.array(list(zip(x1, x2))).reshape(len(x1), 2)
plt.xlim([0, 10])
plt.ylim([0, 10])
plt.title('样本',fontproperties=font)
plt.scatter(x1, x2)
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'b']
markers = ['o', 's', 'D', 'v', '^', 'p', '*', '+']
tests = [2, 3, 4, 5, 8]
subplot_counter = 1
for t in tests:
    subplot_counter += 1
    plt.subplot(3, 2, subplot_counter)
    kmeans_model = KMeans(n_clusters=t).fit(X)
    for i, l in enumerate(kmeans_model.labels_):
        plt.plot(x1[i], x2[i], color=colors[l],marker=markers[l],ls='None')
        plt.xlim([0, 10])
        plt.ylim([0, 10])
        plt.title('K = %s, 轮廓系数 = %.03f' % (t,metrics.silhouette_score(X,kmeans_model.labels_,metric='euclidean')),fontproperties=font)

 

 很显然,这个数据集包括三个类。在K=3的时候轮廓系数是最大的。在K=8的时候,每个类的

样本不仅彼此很接近,而且与其他类的样本也非常接近,因此这时轮廓系数是最小的。

 

 

  • 大小: 3.2 KB
  • 大小: 11.1 KB
  • 大小: 12.8 KB
  • 大小: 11.6 KB
  • 大小: 14 KB
  • 大小: 2 KB
  • 大小: 44.8 KB
  • 大小: 7.6 KB
分享到:
评论
1 楼 crabboy 2018-10-01  
如果 自变量多余2个呢?怎么画图?

相关推荐

    K-Means文本聚类python实现

    然后,我们导入K-Means算法,Python中的`sklearn.cluster.KMeans`库非常方便。设定K值(聚类数量),初始化聚类中心,然后迭代执行以下步骤: 1. **分配样本**:计算每个样本到所有聚类中心的距离,将其分配给最近...

    python内置K-means聚类算法对鸢尾花数据的聚类情况

    上述代码是利用python内置的k-means聚类算法对鸢尾花数据的聚类效果展示,注意在运行该代码时需要采用pip或者其他方式为自己的python安装sklearn以及iris扩展包,其中X = iris.data[:]表示我们采用了鸢尾花数据的四...

    Python用K-means聚类算法进行客户分群的实现

    - `sklearn.cluster.KMeans`:K-means聚类算法的实现。 - `warnings`:用于忽略警告信息,使输出更加简洁。 #### 三、数据处理与可视化 接下来,我们将读取数据文件并进行基本的数据探索和可视化。 **1. 数据读取...

    python中使用k-means聚类.zip_k-means聚类算法_python_python 用kmeans_聚类_聚类 P

    在Python编程环境中,K-Means聚类是一种广泛使用的无监督机器学习算法,用于将数据集划分成不同的簇。这个算法基于一个简单的概念:通过迭代调整数据点的分类,使得同一簇内的数据点尽可能接近,而不同簇之间的数据...

    python实现k-means聚类

    python实现k-means聚类,利用的库有numpy sklearn,利用matplot绘图

    Python从零实现 K-mean 和K-中心点聚类算法的样本数据

    总结来说,K-Means和K-中心点聚类算法是数据挖掘中的基础工具,它们在Python中可以通过简单的代码实现。通过`实验四数据.csv`的数据,我们可以直观地观察这两种算法如何对数据进行分组,并通过调整K值来优化聚类效果...

    实验3-K-means聚类实验_python_

    在本实验中,我们将深入探讨K-means聚类算法,这是一种广泛应用的数据挖掘技术,用于无监督学习中的数据分组。K-means算法基于距离度量,通过迭代过程将数据点分配到最近的聚类中心,直到聚类中心不再显著变化或达到...

    python-d_rearndf_python聚类_python-d_聚类_

    1. **K-Means聚类**:K-Means是最常用的聚类算法之一,通过迭代寻找能够最小化簇内平方误差和的最大化的分组。它需要预先设定簇的数量(k值),然后通过分配数据点到最近的质心来迭代更新簇。 2. **层次聚类**:...

Global site tag (gtag.js) - Google Analytics