K-means

# K均值算法(K-means)聚类 ## 【关键词】K个种子,均值 ## 一、K-means算法原理

聚类的概念:一种无监督的学习,事先不知道类别,自动将相似的对象归到同一个簇中。

K-Means算法是一种聚类分析(cluster analysis)的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法。

K-Means算法主要解决的问题如下图所示。我们可以看到,在图的左边有一些点,我们用肉眼可以看出来有四个点群,但是我们怎么通过计算机程序找出这几个点群来呢?于是就出现了我们的K-Means算法

1.gif

这个算法其实很简单,如下图所示:

2.jpg

从上图中,我们可以看到,A,B,C,D,E是五个在图中点。而灰色的点是我们的种子点,也就是我们用来找点群的点。有两个种子点,所以K=2。

然后,K-Means的算法如下:

  1. 随机在图中取K(这里K=2)个种子点。
  2. 然后对图中的所有点求到这K个种子点的距离,假如点Pi离种子点Si最近,那么Pi属于Si点群。(上图中,我们可以看到A,B属于上面的种子点,C,D,E属于下面中部的种子点)
  3. 接下来,我们要移动种子点到属于他的“点群”的中心。(见图上的第三步)
  4. 然后重复第2)和第3)步,直到,种子点没有移动(我们可以看到图中的第四步上面的种子点聚合了A,B,C,下面的种子点聚合了D,E)。

这个算法很简单,重点说一下“求点群中心的算法”:欧氏距离(Euclidean Distance):差的平方和的平方根

3.gif

### K-Means主要最重大的缺陷——都和初始值有关: K是事先给定的,这个K值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适。(ISODATA算法通过类的自动合并和分裂,得到较为合理的类型数目K) K-Means算法需要用初始随机种子点来搞,这个随机种子点太重要,不同的随机种子点会有得到完全不同的结果。(K-Means++算法可以用来解决这个问题,其可以有效地选择初始点) ### 总结:K-Means算法步骤: 1. 从数据中选择k个对象作为初始聚类中心; 2. 计算每个聚类对象到聚类中心的距离来划分; 3. 再次计算每个聚类中心 4. 计算标准测度函数,直到达到最大迭代次数,则停止,否则,继续操作。 5. 确定最优的聚类中心 ### K-Means算法应用 看到这里,你会说,K-Means算法看来很简单,而且好像就是在玩坐标点,没什么真实用处。而且,这个算法缺陷很多,还不如人工呢。是的,前面的例子只是玩二维坐标点,的确没什么意思。但是你想一下下面的几个问题: 1)如果不是二维的,是多维的,如5维的,那么,就只能用计算机来计算了。 2)二维坐标点的X,Y 坐标,其实是一种向量,是一种数学抽象。现实世界中很多属性是可以抽象成向量的,比如,我们的年龄,我们的喜好,我们的商品,等等,能抽象成向量的目的就是可以让计算机知道某两个属性间的距离。如:我们认为,18岁的人离24岁的人的距离要比离12岁的距离要近,鞋子这个商品离衣服这个商品的距离要比电脑要近,等等。 ## 二、实战 重要参数: - n_clusters:聚类的个数 重要属性: - cluster_centers_ : [n_clusters, n_features]的数组,表示聚类中心点的坐标 - labels_ : 每个样本点的标签 ### 1、聚类实例 导包,使用make_blobs生成随机点cluster_std
import sklearn.datasets as datasets
rs = np.random.RandomState(seed = 10)

# np.random.randint(0,10,size = 5)
rs.randint(0,10,size = 5)
  • 输出

    array([9, 4, 0, 1, 9])

data,target = datasets.make_blobs()


plt.scatter(data[:,0],data[:,1],c = target)
<matplotlib.collections.PathCollection at 0x7fd1ead24da0>

png

target
  • 输出

    array([1, 0, 2, 2, 0, 2, 0, 1, 2, 1, 1, 2, 1, 1, 1, 0, 1, 2, 1, 2, 0, 1,
    1, 2, 1, 1, 0, 1, 2, 0, 0, 0, 1, 1, 0, 2, 1, 2, 1, 0, 1, 1, 1, 2,
    2, 2, 2, 2, 2, 1, 0, 0, 0, 2, 1, 0, 0, 0, 2, 2, 0, 0, 2, 2, 2, 1,
    0, 2, 2, 2, 2, 2, 1, 1, 1, 2, 0, 0, 1, 0, 0, 2, 1, 0, 2, 1, 1, 2,
    0, 0, 1, 0, 2, 0, 0, 0, 1, 0, 0, 0])

建立模型,训练数据,并进行数据预测,使用相同数据

无监督的情况下进行计算,预测
现在机器学习没有目标

绘制图形,显示聚类结果kmeans.cluster_centers

# Kmeans在进行机器学习,如果分类的种类不同,导致结果非常不同,
# 需要我们了解数据
kmeans = KMeans(5)

X_train = data

kmeans.fit(X_train)

# y_ 机器学习预测出来的类别
y_ = kmeans.predict(X_train)

plt.scatter(X_train[:,0],X_train[:,1],c = y_)
<matplotlib.collections.PathCollection at 0x7fd1eac4e9b0>

png

### 2、 实战,三问中国足球几多愁? 导包,3D图像需导包:from mpl_toolkits.mplot3d import Axes3D 读取数据
import numpy as np

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

import pandas as pd

# K-Means k均值聚类 cluster
from sklearn.cluster import KMeans
/usr/lib/python3.5/importlib/_bootstrap.py:222: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88 return f(*args, **kwds) 列名修改为:”国家”,”2006世界杯”,”2010世界杯”,”2007亚洲杯”
data = pd.read_csv('../data/Asiafootball.txt',header = None)

data.columns = ["国家","2006世界杯","2010世界杯","2007亚洲杯"]
data
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
国家2006世界杯2010世界杯2007亚洲杯
0中国50509
1日本2894
2韩国17153
3伊朗25405
4沙特28402
5伊拉克50501
6卡塔尔50409
7阿联酋50409
8乌兹别克斯坦40405
9泰国50509
10越南50505
11阿曼50509
12巴林40409
13朝鲜403217
14印尼50509
X_train = data.iloc[:,1:]
X_train
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
2006世界杯2010世界杯2007亚洲杯
050509
12894
217153
325405
428402
550501
650409
750409
840405
950509
1050505
1150509
1240409
13403217
1450509
k_means = KMeans(n_clusters=3)

# !!! 之前的算法,不同了,没有目标值
# y_target,算法会根据数据特征,自动将这15个球队分成3类
k_means.fit(X_train)
  • 输出

    KMeans(algorithm=’auto’, copy_x=True, init=’k-means++’, max_iter=300,
    n_clusters=3, n_init=10, n_jobs=1, precompute_distances=’auto’,
    random_state=None, tol=0.0001, verbose=0)

使用K-Means进行数据处理,对亚洲球队进行分组,分三组

# 3类
y_ = k_means.predict(X_train)
y_
  • 输出

    array([1, 2, 2, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1], dtype=int32)

for循环打印输出分组后的球队,argwhere()

np.argwhere(y_ == 0).ravel()
  • 输出

    array([ 3, 4, 8, 12, 13])

country = data['国家']

for i in range(3):

    county_index = np.argwhere(y_ == i).ravel()

    print(country[county_index])

    print('\n')

3         伊朗
4         沙特
8     乌兹别克斯坦
12        巴林
13        朝鲜
Name: 国家, dtype: object


0      中国
5     伊拉克
6     卡塔尔
7     阿联酋
9      泰国
10     越南
11     阿曼
14     印尼
Name: 国家, dtype: object


1    日本
2    韩国
Name: 国家, dtype: object

绘制三维立体图形,ax = plt.subplot(projection = ‘3d’)
ax.scatter3D()

X_train.shape
  • 输出

    (15, 3)

type(X_train)
  • 输出

    pandas.core.frame.DataFrame

cluster_centers_ = k_means.cluster_centers_
cluster_centers_
  • 输出

    array([[34.6, 38.4, 7.6],
    [50. , 47.5, 7.5],
    [22.5, 12. , 3.5]])

plt.figure(figsize=(12,8))

axes3d = plt.subplot(projection = '3d')


axes3d.scatter3D(X_train.iloc[:,0],X_train.iloc[:,1],X_train.iloc[:,2],c = y_,cmap = 'rainbow',s = 50)

axes3d.scatter3D(cluster_centers_[:,0],cluster_centers_[:,1],cluster_centers_[:,2],
                 s = 300,c = k_means.predict(cluster_centers_),cmap = 'rainbow')

# 下课修改坐标刻度,应用matplotlib中知识
<mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7fca2068c978>

png

3、聚类实践与常见错误

导包,使用make_blobs创建样本点

import numpy as np
from sklearn.cluster import KMeans
import sklearn.datasets as datasets
import matplotlib.pyplot as plt
# RandomState 随机化状态
a = np.random.RandomState(seed = 10)
a.randint(0, 10, size=100)
  • 输出

    array([9, 4, 0, 1, 9, 0, 1, 8, 9, 0, 8, 6, 4, 3, 0, 4, 6, 8, 1, 8, 4, 1,
    3, 6, 5, 3, 9, 6, 9, 1, 9, 4, 2, 6, 7, 8, 8, 9, 2, 0, 6, 7, 8, 1,
    7, 1, 4, 0, 8, 5, 4, 7, 8, 8, 2, 6, 2, 8, 8, 6, 6, 5, 6, 0, 0, 6,
    9, 1, 8, 9, 1, 2, 8, 9, 9, 5, 0, 2, 7, 3, 0, 4, 2, 0, 3, 3, 1, 2,
    5, 9, 0, 1, 0, 1, 9, 0, 9, 2, 1, 1])

data, target = datasets.make_blobs()
plt.scatter(data[:,0], data[:,1],c=target)
<matplotlib.collections.PathCollection at 0xb3c9710>

png

第一种错误,k值不合适,make_blobs默认中心点三个

# 要使用k-means 那就需要对数据有一定的了解,如果是3类,就一定不能给其他类
km = KMeans(n_clusters=3)
km.fit(data)
  • 输出

    KMeans(algorithm=’auto’, copy_x=True, init=’k-means++’, max_iter=300,
    n_clusters=3, n_init=10, n_jobs=1, precompute_distances=’auto’,
    random_state=None, tol=0.0001, verbose=0)

cluster_centers = km.cluster_centers_
plt.scatter(data[:,0], data[:,1],c=target)
plt.scatter(cluster_centers[:,0], cluster_centers[:,1],c=km.predict(cluster_centers),s=200)
<matplotlib.collections.PathCollection at 0xb6c2ba8>

png

第二种错误,数据偏差
trans = [[0.6,-0.6],[-0.4,0.8]]
X2 = np.dot(X,trans)

# 对数据动了手脚,数据清洗
trans = [[0.6,-0.6],[-0.4,0.8]]
x = np.dot(data,trans)
plt.scatter(x[:,0], x[:,1],c=target)
<matplotlib.collections.PathCollection at 0xb835da0>

png

第三个错误:标准偏差不相同cluster_std

data, target = datasets.make_blobs(cluster_std=[1, 5, 10])
plt.scatter(data[:,0], data[:,1],c=target)
<matplotlib.collections.PathCollection at 0xb579978>

png

km = KMeans(n_clusters=3)
km.fit(data)
  • 输出

    KMeans(algorithm=’auto’, copy_x=True, init=’k-means++’, max_iter=300,
    n_clusters=3, n_init=10, n_jobs=1, precompute_distances=’auto’,
    random_state=None, tol=0.0001, verbose=0)

cluster_centers = km.cluster_centers_
plt.scatter(data[:,0], data[:,1],c=target)
plt.scatter(cluster_centers[:,0], cluster_centers[:,1],c=km.predict(cluster_centers), s=200, cmap='rainbow')
<matplotlib.collections.PathCollection at 0xbfa0320>

png

第四个错误:样本数量不同

# 样本量500个: A:10 B:100 C:390
# 样本严重不平衡
# 在使用KM算法的时候,预测中,A类会变多, B也会变多, c会变少
# 聚类的结果会非常不准确

4、图片压缩

使用聚类压缩图片


img = plt.imread('../data/bird_small.png')
img_shape = img.shape
img_shape

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
bird = plt.imread('./data/bird_small.png')
plt.imshow(bird)
<matplotlib.image.AxesImage at 0xc00a860>

png

bird.shape
  • 输出

    (128, 128, 3)

# 机器学习
X_train = bird.reshape(-1, 3)
# 实例,将颜色分四类
km = KMeans(n_clusters=4)

km.fit(X_train)
  • 输出

    KMeans(algorithm=’auto’, copy_x=True, init=’k-means++’, max_iter=300,
    n_clusters=4, n_init=10, n_jobs=1, precompute_distances=’auto’,
    random_state=None, tol=0.0001, verbose=0)

y_ = km.predict(X_train)
# 找到聚类的中心点(4个均值)

cluster_centers = km.cluster_centers_
# 压缩颜色最好使用png
# jpg 0-255 一种256种 uint8
# png 0-1 float32 
# 选取了4个最具有代表性的颜色,将这4个颜色,按照分类索引,重新生成一张照片
new_bird = cluster_centers[y_]
plt.imshow(new_bird.reshape(128,128,3))
plt.imsave(fname='./data/new_bird.png', arr = new_bird.reshape(128,128,3))
<matplotlib.image.AxesImage at 0xc06ceb8>

png

5.K-Means图片颜色分类

导包 from sklearn.metrics import pairwise_distances_argmin

import sklearn.datasets as datasets
image = datasets.load_sample_image('china.jpg')

plt.figure(figsize=(12, 9))

plt.imshow(image)
<matplotlib.image.AxesImage at 0xc93d400>

png

image.shape
  • 输出

    (427, 640, 3)

X_train = image.reshape(-1,3)
# pandas
# unique()
from pandas import Series, DataFrame

df = DataFrame(X_train)
# 查看重复的颜色值
df.duplicated().sum()
  • 输出

    176665

# 不重复的颜色
df.drop_duplicates().shape
  • 输出

    (96615, 3)

# 分成64类
km = KMeans(64)
# 因为根据欧式距离,点又多
km.fit(X_train)
  • 输出

    KMeans(algorithm=’auto’, copy_x=True, init=’k-means++’, max_iter=300,
    n_clusters=64, n_init=10, n_jobs=1, precompute_distances=’auto’,
    random_state=None, tol=0.0001, verbose=0)

y_ = km.predict(X_train)

加载图片/创建模型/训练数据

# 64组颜色
cluster_centers = km.cluster_centers_
# 生成一张新的图片
new_china = cluster_centers[y_]/255
plt.imshow(new_china.reshape(427,640,3))
<matplotlib.image.AxesImage at 0xf3b01d0>

png

plt.imsave(fname='./data/new_china.png', arr=new_china.reshape(427,640,3))

压缩长和宽

# 压缩尺寸
# cv2
# ndimage.zoom()
import scipy.ndimage as ndimage
china = new_china.reshape(427,640,3) * 255
china = china.astype('uint8')
china_small = ndimage.zoom(china, zoom=(0.5, 0.5, 1))
C:\Users\Administrator\Anaconda3\lib\site-packages\scipy\ndimage\interpolation.py:616: UserWarning: From scipy 0.13.0, the output shape of zoom() is calculated with round() instead of int() - for these inputs the size of the returned array has changed.
  "the returned array has changed.", UserWarning)
plt.imshow(china_small)
<matplotlib.image.AxesImage at 0xf10c390>

png

plt.imsave('./data/small1_china.jpg', china_small)
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【摘要】 目前,对于聚类问题的研究普遍存在于社会生活中的各个领域,如模式识别、图像处理、机器学习和统计学等。关于对生活中各种各样的数据的聚类分类问题已经成为众多学者的研究热题之一。聚类和分类的区别在于,聚类没有任何先验知识可循,要通过数据自身的特点,将数据自动的划分到不同的类别中。聚类的基本形式定义为“在已给的数据集合中寻找数据点集的同类集合。每一个集合叫做一个类,并确定了一个区域,在区域中对象的密度高于其他区域中的密度。”聚类方法有很多种,其中最简单的形式便是划分式聚类,划分式聚类试图将给定的数据集合分割成不相交的子集,使具体的聚类准则是最优的。实际中应用最广泛的准则是聚类误差平方和准则,即对于每一个点都计算它到相应的聚类中心点的平方距离,并对数据集合上的所有点的距离进行求和。一种最流行的基于最小聚类误差平法和的聚类方法是K-均值算法。然而,K-均值算法是一个局部搜索的算法,它存在一些严重的不足,比如K值需要预先确定、聚类结果的好坏依赖于初始点的选取。为了解决这些问题,这个领域的研究者开发了很多其他的一些技术,试图基于全局最优化的方法来解决聚类问题(比如模拟退火算法、遗传算法等)。然而这些技术并没有得到广泛的认可,在许多实际应用中应用最多的还是反复利用K-均值算法。K-均值算法是一种基于划分的聚类算法,它通过不断的迭代来进行聚类,当算法收敛到一个结束条件时就终止迭代过程,输出聚类结果。由于其算法思想简便,又容易实现对大规模数据的聚类,因此K-均值算法已成为一种最常用的聚类算法之一K-均值算法能找到关于聚类误差的局部的最优解,是一个能应用在许多聚类问题上的快速迭代算法。它是一种以点为基础的聚类算法,以随机选取的初始点为聚类中心,迭代地改变聚类中心来使聚类误差最小化。这种方法最主要的不足就是对于初始聚类中心点位置的选取敏感。因此,为了得到近似最优解,初始聚类中心的位置必须安排的有差异。本文就K-均值聚类算法的聚类结果依赖于初始中心,而且经常收敛于局部最优解,而非全局最优解,以及聚类类别数K需要事先给定这两大缺憾展开研究。提出了分别解决这两个问题的算法各一个首先,本文将Hae-Sang等人的快速K-中心点算法确定初始中心点的思想应用于Aristidis Likas的全局K-均值聚类算法中下一个簇的初始中心选择上,提出一种改进的全局K-均值聚类算法,试图寻找一个周围样本点分布比较密集,且距离现有簇的中心都较远的样本点,将其作为下一个簇的最佳初始中心。通过对UCI机器学习数据库数据及人工随机模拟数据的测试,证明本文算法与Aristidis Likas的全局K-均值聚类算法和快速全局K-均值聚类算法比,在不影响聚类误差平方和的前提下,聚类时间更短,具有更好的性能。同时,本文介绍了自组织特征映射网络(Self-Organizing Feature Map, SOFM)的相关内容,SOFM网络是将多维数据映射到低维规则网格中,可以有效的进行大规模的数据挖掘,其特点是速度快,但是分类的精度不高。而K-均值聚类算法,是一种通过不断迭代调整聚类质心的算法,其特点是精度高,主要用于中小数据集的分类,但是聚类速度比较慢。因此,本文在分析了基于自组织特征映射网络聚类的学习过程,权系数自组织过程中邻域函数,以及学习步长的一般取值问题后,给出了基于自组织特征映射网络聚类实现的具体算法,将自组织特征网络与K-均值聚类算法相结合,提出了一种基于自组织映射网络的聚类方法,来实现对输入模式进行聚类,实现K-均值聚类算法的聚类类别数的自动确定。同时通过实验进行仿真实现,证明该算法的有效性。 还原 【Abstract】 Clustering is a fundamental problem that frequently arises in a great variety of fields such as pattern recognition, image processing, machine learning and statistics. In general, clustering is defined as the problem of finding homogeneous groups of samples in a given data set. Each of these groups is called a cluster and can be defined as a region in which the density of exemplars is locally higher than in other regions.The simplest form of clustering is partition clustering w

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值