K-means入门学习

  • 一、算法概述
  • 二、算法思想
  • 三、算法实现步骤
  • 四、算法图解
  • 五、算法优缺点
  • 六、k-means算法python实现
    • 6.1 sklearn聚类
    • 6.2 各省份消费数据聚类
    • 6.3 常规方法python实现
  • 七、相关参数调整
  • 八、优化算法K-means++
    • 8.1 kmeans不足之处
    • 8.2 kmeans++
    • 8.3 层次聚类

一、算法概述

K-means聚类算法也称k均值聚类算法,是集简单和经典于一身的基于距离的聚类算法。它采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

K-Means算法主要解决的问题如下图所示。我们可以看到,在图的左边有一些点,我们可以看出来有三个点群,但是我们怎么才能将三个点群分为图右边的三个集群,这就是k-means算法能够解决的问题。

二、算法思想

K-means聚类算法是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

三、算法实现步骤

  1. 指定需要划分的簇的个数K值(类的个数);
  2. 随机地选择K个数据对象作为初始的聚类中心(不一定要是我们的样本点,可以随机生成)
  3. 计算其余的各个数据对象到这K个初始聚类中心的距离,把数据对象划归到距离它最近的那个中心所处在的簇类中
  4. 调整新类并且重新计算出新类的中心(每个新集合质心)
  5. 循环步骤三和四,看中心是否收敛(不变),如果收敛或达到迭代次数则停止循环

流程图如下:

四、算法图解

首先随机选择三个聚类中心;然后重复调整聚类中心位置;最终收敛,形成三个簇。

五、算法优缺点

优点

  1. 对处理大数据集,该算法是相对高效率的。
  2. 原理比较简单,实现也是很容易,收敛速度快。
  3. 当结果簇是密集的,而簇与簇之间区别明显时, 它的效果较好。
  4. 主要需要调参的参数仅仅是簇数k。

缺点

  1. 要求用户必须事先给出要生成的簇的数目K。
  2. K值需要预先给定,很多情况下K值的估计是非常困难的。
  3. K-Means算法对初始选取的质心点是敏感的,不同的随机种子点得到的聚类结果完全不同 ,对结果影响很大。
  4. 对噪音和异常点比较的敏感。用来检测异常值。
  5. 采用迭代方法,可能只能得到局部的最优解,而无法得到全局的最优解。

六、k-means算法python实现

6.1 sklearn聚类

  1. make_blobs函数是为聚类产生数据集,产生一个数据集和相应的标签
    make_blobs方法
    sklearn.datasets.make_blobs(n_samples=100,n_features=2,centers=3, cluster_std=1.0,center_box=(-10.0,10.0),shuffle=True,random_state=None)
    n_samples:表示数据样本点个数,默认值100
    n_features:是每个样本的特征(或属性)数,也表示数据的维度,默认值是2
    centers:表示类别数(标签的种类数),默认值3
    cluster_std:表示每个类别的方差,例如我们希望生成2类数据,其中一类比另一类具有更大的方差,可以将cluster_std设置为[1.0,3.0],浮点数或者浮点数序列,默认值1.0
    center_box:中心确定之后的数据边界,默认值(-10.0, 10.0)
    shuffle:将数据进行洗乱,默认值是True
    random_state:官网解释是随机生成器的种子,可以固定生成的数据,给定数之后,每次生成的数据集就是固定的。若不给定值,则由于随机性将导致每次运行程序所获得的的结果可能有所不同。在使用数据生成器练习机器学习算法练习或python练习时建议给定数值。
  2. 生成数据
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
#参数:
# n_samples=100  样本数量
# n_features=2   特征数量
# centers=3      中心点
#返回值:
# X_train:  测试集
# y_train: 特征值
X_train,y_train = make_blobs(n_samples=100, n_features=2, centers=3)
plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
plt.show()

数据展示:

3. 建立模型训练

#参数
# n_clusters  将预测结果分为几簇
kmeans = KMeans(n_clusters=3)  # 获取模型
kmeans.fit(X_train)  #这里不需要给他答案 只把要分类的数据给他 即可
  1. 预测
predict_y = kmeans.predict(X_train)
plt.scatter(X_train[:,0],X_train[:,1],c=predict_y)  #预测结果
plt.show()

预测结果:

6.2 各省份消费数据聚类

  1. 导入数据
from sklearn.cluster import KMeans
import pandas as pd
df = pd.read_excel('data.xlsx',sheet_name="人均消费(元)")
data = df.iloc[:,1:]
print(data)

数据显示:

      食品     衣着   家庭设备  医疗    交通     娱乐      居住    杂项
0   2959.19  730.79  749.41  513.34  467.87  1141.82   478.42  457.64
1   2459.77  495.47  697.33  302.87  284.19   735.97   570.84  305.08
2   1495.63  515.90  362.37  285.32  272.95   540.58   364.91  188.63
3   1406.33  477.77  290.15  208.57  201.50   414.72   281.84  212.10
4   1303.97  524.29  254.83  192.17  249.81   463.09   287.87  192.96
5   1730.84  553.90  246.91  279.81  239.18   445.20   330.24  163.86
6   1561.86  492.42  200.49  218.36  220.69   459.62   360.48  147.76
7   1410.11  510.71  211.88  277.11  224.65   376.82   317.61  152.85
8   3712.31  550.74  893.37  346.93  527.00  1034.98   720.33  462.03
9   2207.58  449.37  572.40  211.92  302.09   585.23   429.77  252.54
10  2629.16  557.32  689.73  435.69  514.66   795.87   575.76  323.36
11  1844.78  430.29  271.28  126.33  250.56   513.18   314.00  151.39
12  2709.46  428.11  334.12  160.77  405.14   461.67   535.13  232.29
13  1563.78  303.65  233.81  107.90  209.70   393.99   509.39  160.12
14  1675.75  613.32  550.71  219.79  272.59   599.43   371.62  211.84
15  1427.65  431.79  288.55  208.14  217.00   337.76   421.31  165.32
16  1942.23  512.27  401.39  206.06  321.29   697.22   492.60  226.45
17  1783.43  511.88  282.84  201.01  237.60   617.74   523.52  182.52
18  3055.17  353.23  564.56  356.27  811.88   873.06  1082.82  420.81
19  2033.87  300.82  338.65  157.78  329.06   621.74   587.02  218.27
20  2057.86  186.44  202.72  171.79  329.65   477.17   312.93  279.19
21  2303.29  589.99  516.21  236.55  403.92   730.05   438.41  225.80
22  1974.28  507.76  344.79  203.21  240.24   575.10   430.36  223.46
23  1673.82  437.75  461.61  153.32  254.66   445.59   346.11  191.48
24  2194.25  537.01  369.07  249.54  290.84   561.91   407.70  330.95
25  2646.61  839.70  204.44  209.11  379.30   371.04   269.59  389.33
26  1472.95  390.89  447.95  259.51  230.61   490.90   469.10  191.34
27  1525.57  472.98  328.90  219.86  206.65   449.69   249.66  228.19
28  1654.69  437.77  258.78  303.00  244.93   479.53   288.56  236.51
29  1375.46  480.89  273.84  317.32  251.08   424.75   228.73  195.93
30  1608.82  536.05  432.46  235.82  250.28   541.30   344.85  214.40
  1. 建立模型并训练数据
k=3
model = KMeans(n_clusters= k,init='k-means++')
clf = model.fit(data)
predict_y = clf.predict(data)
  1. 聚类结果
print(df[predict_y==0]['省份'])
print(df[predict_y==1]['省份'])
print(df[predict_y==2]['省份'])

结果显示:

2      河北
3      山西
4     内蒙古
5      辽宁
6      吉林
7     黑龙江
11     安徽
13     江西
14     山东
15     河南
17     湖北
23     贵州
26     陕西
27     甘肃
28     青海
29     宁夏
30     新疆
Name: 省份, dtype: object
1     天津
9     江苏
10    浙江
12    福建
16    湖南
19    广西
20    海南
21    重庆
22    四川
24    云南
25    西藏
Name: 省份, dtype: object
0     北京
8     上海
18    广东
Name: 省份, dtype: object

6.3 常规方法python实现

各城市消费水平聚类

import random
import pandas as pd
import numpy as np#%%
# 计算欧拉距离
def calcDis(dataSet, centroids, k):clalist = []for data in dataSet:diff = np.tile(data, (k, 1)) - centroidssquaredDiff = diff ** 2  # 平方squaredDist = np.sum(squaredDiff, axis=1)  # 和  (axis=1表示行)distance = squaredDist ** 0.5  # 开根号clalist.append(distance)clalist = np.array(clalist)  # 返回一个每个点到质点的距离len(dateSet)*k的数组return clalist# 计算质心
def classify(dataSet, centroids, k):# 计算样本到质心的距离clalist = calcDis(dataSet, centroids, k)# 分组并计算新的质心minDistIndices = np.argmin(clalist, axis=1)  # axis=1 表示求出每行的最小值的下标newCentroids = pd.DataFrame(dataSet).groupby(minDistIndices).mean()  # DataFramte(dataSet)对DataSet分组,groupby(min)按照min进行统计分类,mean()对分类结果求均值newCentroids = newCentroids.values# 计算变化量changed = newCentroids - centroidsreturn changed, newCentroids# 使用k-means分类
def kmeans(dataSet, k):# 随机取质心# random.sample(list类型数据)centroids = random.sample(list(dataSet), k)# 更新质心 直到变化量全为0changed, newCentroids = classify(dataSet, centroids, k)while np.any(changed != 0):changed, newCentroids = classify(dataSet, newCentroids, k)centroids = sorted(newCentroids.tolist())  # tolist()将矩阵转换成列表 sorted()排序# 根据质心计算每个集群cluster = []clalist = calcDis(dataSet, centroids, k)  # 调用欧拉距离minDistIndices = np.argmin(clalist, axis=1)for i in range(k):cluster.append([])for i, j in enumerate(minDistIndices):  # enymerate()可同时遍历索引和遍历元素cluster[j].append(dataSet[i])return centroids, cluster, minDistIndices# 创建数据集
def createDataSet():df = pd.read_excel(r"data.xlsx", sheet_name="人均消费(元)")data = df.iloc[:, 1:]return df,np.array(data)if __name__ == '__main__':df,dataSet = createDataSet()centroids, cluster, minDist = kmeans(dataSet, 3)print('质心为:%s' % centroids)print('集群为:%s' % cluster)print(df[minDist == 0]['省份'])print(df[minDist == 1]['省份'])print(df[minDist == 2]['省份'])

聚类结果:

2      河北
3      山西
4     内蒙古
5      辽宁
6      吉林
7     黑龙江
11     安徽
13     江西
14     山东
15     河南
17     湖北
23     贵州
26     陕西
27     甘肃
28     青海
29     宁夏
30     新疆
Name: 省份, dtype: object
1     天津
9     江苏
12    福建
16    湖南
19    广西
20    海南
21    重庆
22    四川
24    云南
25    西藏
Name: 省份, dtype: object
0     北京
8     上海
10    浙江
18    广东
Name: 省份, dtype: object

七、相关参数调整

以下程序来源链接: K均值算法

  1. 标准差cluster_std不相同
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# cluster_std 各个中心的标准差
X_train,y_train = make_blobs(n_samples=500, n_features=2, centers=3, cluster_std=[1.0,2.0,3.0])
#参数
# n_clusters  将预测结果分为几簇
kmeans = KMeans(n_clusters=3)  # 获取模型
kmeans.fit(X_train)
predict_y = kmeans.predict(X_train)
plt.scatter(X_train[:,0],X_train[:,1],c=y_train) # 原结果
plt.show()
plt.scatter(X_train[:,0],X_train[:,1],c=predict_y)  #预测结果
plt.show()

原始数据:

聚类结果:

2. 样本数量不同

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np
# cluster_std 各个中心的标准差
X_train,y_train = make_blobs(n_samples=1500, n_features=2, centers=3)
# 创建训练集
X1 = X_train[y_train==0]        # X1中的这些点 目标值都是0
X2 = X_train[y_train==1][:100]  # X2中的这些点 目标值都是1
X3 = X_train[y_train==2][:10]   # X3中的这些点 目标值都是2# 将三个合为一个训练集
X_train = np.concatenate((X1,X2,X3))
# 创建结果集
# 前500个为0  再来100个1  再来10个2
y_train = [0]*500+[1]*100+[2]*10
plt.scatter(X_train[:,0],X_train[:,1],c=y_train) # 原结果
plt.show()
#参数
# n_clusters  将预测结果分为几簇
kmeans = KMeans(n_clusters=3)  # 获取模型
kmeans.fit(X_train)
predict_y = kmeans.predict(X_train)plt.scatter(X_train[:,0],X_train[:,1],c=predict_y)  #预测结果
plt.show()

原始数据:

聚类结果:

八、优化算法K-means++

8.1 kmeans不足之处

从KmeansKmeansKmeans聚类算法的原理可知,在正式聚类之前首先需要完成的就是初始化kkk个簇中心。使得收敛情况严重依赖于簇中心的初始化状况。如果在初始化过程中很不巧的将kkk个(或大多数)簇中心都初始化了到同一个簇中,那么在这种情况下聚类算法很大程度上都不会收敛到全局最小值。也就是说,当簇中心初始化的位置不得当时,聚类结果将会出现严重的错误。

8.2 kmeans++

k-means++算法选择初始聚类中心的基本原则是:初始的聚类中心之间的相互距离要尽可能的远
算法描述如下
(只对K-means算法“初始化K个聚类中心” 这一步进行了优化)

  1. 随机选取一个样本作为第一个聚类中心;
  2. 计算每个样本与当前已有聚类中心的最短距离(即与最近一个聚类中心的距离),这个值越大,表示被选取作为聚类中心的概率较大;最后,用轮盘法(依据概率大小来进行抽选)选出下一个聚类中心;
  3. 重复步骤二,直到选出K个聚类中心。选出初始点后,就继续使用标准的K-means算法了。
    程序实现
def get_cent(points, k):'''kmeans++的初始化聚类中心的方法:param points: 样本:param k: 聚类中心的个数:return: 初始化后的聚类中心'''m, n = np.shape(points)cluster_centers = np.mat(np.zeros((k, n)))# 1、随机选择一个样本点作为第一个聚类中心index = np.random.randint(0, m)cluster_centers[0, ] = np.copy(points[index, ])  # 复制函数,修改cluster_centers,不会影响points# 2、初始化一个距离序列d = [0.0 for i in range(m)]for i in range(1, k):sum_all = 0for j in range(m):# 3、对每一个样本找到最近的聚类中心点d[j] = nearest(points[j, ], cluster_centers[0:i, ])# 4、将所有的最短距离相加sum_all += d[j]# 5、取得sum_all之间的随机值sum_all *= random()# 6、获得距离最远的样本点作为聚类中心点for j, di in enumerate(d):  # enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同事列出数据和数据下标一般用在for循环中sum_all -= diif sum_all > 0:continuecluster_centers[i] = np.copy(points[j, ])breakreturn cluster_centers

8.3 层次聚类

参考来源:数学建模清风老师课件

层次聚类的算法流程

  1. 将每个对象看作一类,计算两两之间的最小距离;
  2. 将距离最小的两个类合并成一个新类;
  3. 重新计算新类与所有类之间的距离;
  4. 重复二三两步,直到所有类最后合并成一类;

算法图解

程序实现

# 调包
import matplotlib.pyplot as plt
import pandas as pd
import scipy.cluster.hierarchy as shc # 层次聚类
# 防止中文乱码
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
# 加载数据
df = pd.read_excel('data.xlsx',sheet_name="人均消费(元)")
print(df.head())
# 绘图
plt.figure(figsize=(16,10),dpi=100)
plt.title('省份消费数据聚类树状图',fontsize=22)
dend = shc.dendrogram(shc.linkage(df[['食品','衣着','家庭设备','医疗','交通','娱乐','居住','杂项']],
method='ward'),labels=df['省份'].values,color_threshold=100)
plt.xticks(fontsize=12)
plt.savefig('树状图.png') # 保存图片
plt.show()

聚类树状图

本文为学习过程记录,根据学习情况继续更新。

K-means原理与算法改进及其python实现相关推荐

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

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

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

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

  3. 【Python】实现二维装箱Bottom-Left算法及用人工蜂群算法改进

    目录 1 题目 2 装箱算法 2.1 所有装箱算法 2.2 Bottom-Left具体算法过程 3 Python 实现 3.1 main.py主函数 3.2 overlap函数 3.3 finalPo ...

  4. K均值(K-means)聚类算法原理与代码详解

    0. 算法原理: 上述过程简单描述: a: 初始数据 b: 选择质点 c: 根据质点划分 d: 求均值,更新质心点 e: 划分 f: 更新质心点 1. 代码实现: # K means 教程# 0. 引 ...

  5. 第k大的数python代码_Python实现查找数组中任意第k大的数字算法示例

    本文实例讲述了Python实现查找数组中任意第k大的数字算法.分享给大家供大家参考,具体如下: 模仿partion方法,当high=low小于k的时候,在后半部分搜索,当high=low大于k的时候, ...

  6. 聚类算法中 K均值聚类(KMeans)的python实现

    ** 聚类算法中 K均值聚类(KMeans)的python实现 ** import numpy as np import matplotlib.pyplot as plt from sklearn.d ...

  7. KNN算法原理及简单改进

    KNN算法 1. 什么是KNN算法 简单来说,就是根据周围几个邻居的类别来判断自己的类别 1.1 KNN概念 KNN算法全称K Nearest Neighbor 定义:如果一个样本在特征空间中的k个最 ...

  8. opencvkcf算法改进_KCF跟踪算法原理 入门详解

    一.算法介绍 KCF全称为Kernel Correlation Filter 核相关滤波算法.是在2014年由Joao F. Henriques, Rui Caseiro, Pedro Martins ...

  9. Udacity机器人软件工程师课程笔记(二十一) - 对点云进行集群可视化 - 聚类的分割 - K-means|K均值聚类, DBSCAN算法

    聚类的分割 1.K-均值聚类 (1)K-均值聚类介绍 k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心 ...

最新文章

  1. java语言环境变量_JAVA语言环境变量的设置教程
  2. Acronis移动方案(四)
  3. javaweb 之javascript 结合
  4. Tickets HDU - 1260
  5. uva 11490 ——Just Another Problem
  6. python去年软件排行_2017年编程语言排行榜,Python位居榜首(C语言需求最大)
  7. (最短路)Shopping
  8. anaconda卸载tensorflow时,收集不到包的解决方法
  9. WPF学习笔记——在“System.Windows.StaticResourceExtension”上提供值时引发了异常
  10. MATLAB局部放大
  11. 4600u黑苹果 r5_黑苹果集显hd4400、hd4600显卡Clover引导驱动方法教程
  12. 龙芯芯片CPU的产品路线说明
  13. java 密码 星号显示_Java多线程 例子 cmd窗口下 实现输入密码星号显示
  14. 关于曼哈顿距离的最小生成树 POJ3241
  15. 计算机名词解释(计算机科学导论)
  16. 计算机上用户名怎么设置,电脑用户名,详细教您电脑用户名怎么修改
  17. 携手互联网企业10巨头设VC基金
  18. 用boot camp助理装win 7时卡在了“正在拷贝windows文件”
  19. 自学前端第十天 : CSS怪异盒子模型
  20. opencv学习日志15-统计焊点个数并输出

热门文章

  1. java第七封印游戏_第七封印的游戏任务
  2. 上次吹的牛实现后,李彦宏又在百度世界大会立了三个flag!
  3. 财务Financial Affairs
  4. 数据查询必备技能SQL调优:Mysql什么情况下不走索引
  5. 火焰焰心matlab,[转载]酒精灯火焰的温度真的是外焰最高吗?
  6. MdEditor-v3中上传照片的前后端对接(图片上传至又拍云云储存)
  7. 80后相亲面面观 男生找富婆不怕倒插门。80后的特点!你占几样?
  8. Go语言基础入门(处理JSON)
  9. 北师大计算机和北邮哪个好考,同在首都的,北京师范大学和北京邮电大学,哪所实力更强?...
  10. 这个项目把100多个知名网站都克隆出来了!