KMeans算法是一种无监督学习,它会将相似的对象归到同一类中。

其基本思想是:

1.随机计算k个类中心作为起始点。

2. 将数据点分配到理其最近的类中心。

3.移动类中心。

4.重复2,3直至类中心不再改变或者达到限定迭代次数。

具体的实现如下:

  1. from numpy import *
  2. import matplotlib.pyplot as plt
  3. import pandas as pd
  4. # Load dataset
  5. url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
  6. names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
  7. dataset = pd.read_csv(url, names=names)
  8. dataset['class'][dataset['class']=='Iris-setosa']=0
  9. dataset['class'][dataset['class']=='Iris-versicolor']=1
  10. dataset['class'][dataset['class']=='Iris-virginica']=2
  11. #对类别进行编码,3个类别分别赋值0,1,2
  12. #算距离
  13. def distEclud(vecA, vecB): #两个向量间欧式距离
  14. return sqrt(sum(power(vecA - vecB, 2))) #la.norm(vecA-vecB)
  15. #初始化聚类中心:通过在区间范围随机产生的值作为新的中心点
  16. def randCent(dataSet, k):
  17. #获取特征维度
  18. n = shape(dataSet)[1]
  19. #创建聚类中心0矩阵 k x n
  20. centroids = mat(zeros((k,n)))
  21. #遍历n维特征
  22. for j in range(n):
  23. #第j维特征属性值min ,1x1矩阵
  24. minJ = min(dataSet[:,j])
  25. #区间值max-min,float数值
  26. rangeJ = float(max(dataSet[:,j]) - minJ)
  27. #第j维,每次随机生成k个中心
  28. centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))
  29. return centroids
  30. def randChosenCent(dataSet,k):
  31. # 样本数
  32. m=shape(dataSet)[0]
  33. # 初始化列表
  34. centroidsIndex=[]
  35. #生成类似于样本索引的列表
  36. dataIndex=list(range(m))
  37. for i in range(k):
  38. #生成随机数
  39. randIndex=random.randint(0,len(dataIndex))
  40. #将随机产生的样本的索引放入centroidsIndex
  41. centroidsIndex.append(dataIndex[randIndex])
  42. #删除已经被抽中的样本
  43. del dataIndex[randIndex]
  44. #根据索引获取样本
  45. centroids = dataSet.iloc[centroidsIndex]
  46. return mat(centroids)
  47. def kMeans(dataSet, k):
  48. # 样本总数
  49. m = shape(dataSet)[0]
  50. # 分配样本到最近的簇:存[簇序号,距离的平方]
  51. # m行 2 列
  52. clusterAssment = mat(zeros((m, 2)))
  53. # step1:
  54. # 通过随机产生的样本点初始化聚类中心
  55. centroids = randChosenCent(dataSet, k)
  56. print('最初的中心=', centroids)
  57. # 标志位,如果迭代前后样本分类发生变化值为Tree,否则为False
  58. clusterChanged = True
  59. # 查看迭代次数
  60. iterTime = 0
  61. # 所有样本分配结果不再改变,迭代终止
  62. while clusterChanged:
  63. clusterChanged = False
  64. # step2:分配到最近的聚类中心对应的簇中
  65. for i in range(m):
  66. # 初始定义距离为无穷大
  67. minDist = inf;
  68. # 初始化索引值
  69. minIndex = -1
  70. # 计算每个样本与k个中心点距离
  71. for j in range(k):
  72. # 计算第i个样本到第j个中心点的距离
  73. distJI = distEclud(centroids[j, :], dataSet.values[i, :])
  74. # 判断距离是否为最小
  75. if distJI < minDist:
  76. # 更新获取到最小距离
  77. minDist = distJI
  78. # 获取对应的簇序号
  79. minIndex = j
  80. # 样本上次分配结果跟本次不一样,标志位clusterChanged置True
  81. if clusterAssment[i, 0] != minIndex:
  82. clusterChanged = True
  83. clusterAssment[i, :] = minIndex, minDist ** 2 # 分配样本到最近的簇
  84. iterTime += 1
  85. sse = sum(clusterAssment[:, 1])
  86. print('the SSE of %d' % iterTime + 'th iteration is %f' % sse)
  87. # step3:更新聚类中心
  88. for cent in range(k): # 样本分配结束后,重新计算聚类中心
  89. # 获取该簇所有的样本点
  90. ptsInClust = dataSet.iloc[nonzero(clusterAssment[:, 0].A == cent)[0]]
  91. # 更新聚类中心:axis=0沿列方向求均值。
  92. centroids[cent, :] = mean(ptsInClust, axis=0)
  93. return centroids, clusterAssment
  94. def kMeansSSE(dataSet,k,distMeas=distEclud, createCent=randChosenCent):
  95. m = shape(dataSet)[0]
  96. #分配样本到最近的簇:存[簇序号,距离的平方]
  97. clusterAssment=mat(zeros((m,2)))
  98. #step1:#初始化聚类中心
  99. centroids = createCent(dataSet, k)
  100. print('initial centroids=',centroids)
  101. sseOld=0
  102. sseNew=inf
  103. iterTime=0 #查看迭代次数
  104. while(abs(sseNew-sseOld)>0.0001):
  105. sseOld=sseNew
  106. #step2:将样本分配到最近的质心对应的簇中
  107. for i in range(m):
  108. minDist=inf;minIndex=-1
  109. for j in range(k):
  110. #计算第i个样本与第j个质心之间的距离
  111. distJI=distMeas(centroids[j,:],dataSet.values[i,:])
  112. #获取到第i样本最近的质心的距离,及对应簇序号
  113. if distJI<minDist:
  114. minDist=distJI;minIndex=j
  115. clusterAssment[i,:]=minIndex,minDist**2 #分配样本到最近的簇
  116. iterTime+=1
  117. sseNew=sum(clusterAssment[:,1])
  118. print('the SSE of %d'%iterTime + 'th iteration is %f'%sseNew)
  119. #step3:更新聚类中心
  120. for cent in range(k):
  121. #样本分配结束后,重新计算聚类中心
  122. ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]
  123. #按列取平均,mean()对array类型
  124. centroids[cent,:] = mean(ptsInClust, axis=0)
  125. return centroids, clusterAssment
  126. # 2维数据聚类效果显示
  127. def datashow(dataSet, k, centroids, clusterAssment): # 二维空间显示聚类结果
  128. from matplotlib import pyplot as plt
  129. num, dim = shape(dataSet) # 样本数num ,维数dim
  130. if dim != 2:
  131. print('sorry,the dimension of your dataset is not 2!')
  132. return 1
  133. marksamples = ['or', 'ob', 'og', 'ok', '^r', '^b', '<g'] # 样本图形标记
  134. if k > len(marksamples):
  135. print('sorry,your k is too large,please add length of the marksample!')
  136. return 1
  137. # 绘所有样本
  138. for i in range(num):
  139. markindex = int(clusterAssment[i, 0]) # 矩阵形式转为int值, 簇序号
  140. # 特征维对应坐标轴x,y;样本图形标记及大小
  141. plt.plot(dataSet.iat[i, 0], dataSet.iat[i, 1], marksamples[markindex], markersize=6)
  142. # 绘中心点
  143. markcentroids = ['o', '*', '^'] # 聚类中心图形标记
  144. label = ['0', '1', '2']
  145. c = ['yellow', 'pink', 'red']
  146. for i in range(k):
  147. plt.plot(centroids[i, 0], centroids[i, 1], markcentroids[i], markersize=15, label=label[i], c=c[i])
  148. plt.legend(loc='upper left')
  149. plt.xlabel('sepal length')
  150. plt.ylabel('sepal width')
  151. plt.title('k-means cluster result') # 标题
  152. plt.show()
  153. # 画出实际图像
  154. def trgartshow(dataSet, k, labels):
  155. from matplotlib import pyplot as plt
  156. num, dim = shape(dataSet)
  157. label = ['0', '1', '2']
  158. marksamples = ['ob', 'or', 'og', 'ok', '^r', '^b', '<g']
  159. # 通过循环的方式,完成分组散点图的绘制
  160. for i in range(num):
  161. plt.plot(datamat.iat[i, 0], datamat.iat[i, 1], marksamples[int(labels.iat[i, 0])], markersize=6)
  162. for i in range(0, num, 50):
  163. plt.plot(datamat.iat[i, 0], datamat.iat[i, 1], marksamples[int(labels.iat[i, 0])], markersize=6,
  164. label=label[int(labels.iat[i, 0])])
  165. plt.legend(loc='upper left')
  166. # 添加轴标签和标题
  167. plt.xlabel('sepal length')
  168. plt.ylabel('sepal width')
  169. plt.title('iris true result') # 标题
  170. # 显示图形
  171. plt.show()
  172. # label=labels.iat[i,0]
  173. #聚类前,绘制原始的样本点
  174. def originalDatashow(dataSet):
  175. #样本的个数和特征维数
  176. num,dim=shape(dataSet)
  177. marksamples=['ob'] #样本图形标记
  178. for i in range(num):
  179. plt.plot(datamat.iat[i,0],datamat.iat[i,1],marksamples[0],markersize=5)
  180. plt.title('original dataset')
  181. plt.xlabel('sepal length')
  182. plt.ylabel('sepal width') #标题
  183. plt.show()
  184. if __name__ == '__main__':
  185. # =====kmeans聚类
  186. # # #获取样本数据
  187. datamat = dataset.loc[:, ['sepal-length', 'sepal-width']]
  188. # 真实的标签
  189. labels = dataset.loc[:, ['class']]
  190. # #原始数据显示
  191. originalDatashow(datamat)
  192. # #*****kmeans聚类
  193. k = 3 # 用户定义聚类数
  194. mycentroids, clusterAssment = kMeans(datamat, k)
  195. # mycentroids,clusterAssment=kMeansSSE(datamat,k)
  196. # 绘图显示
  197. datashow(datamat, k, mycentroids, clusterAssment)
  198. trgartshow(datamat, 3, labels)

下面,使用TensorFlow,实现如下:

  1. import tensorflow as tf
  2. import numpy as np
  3. from tensorflow.contrib.factorization import KMeans
  4. import os
  5. os.environ['CUDA_VISIBLE_DEVICES']=''
  6. from tensorflow.examples.tutorials.mnist import input_data
  7. mnist = input_data.read_data_sets('/tmp/data',one_hot=True)
  8. full_data_x = mnist.train.images
  9. num_steps = 50
  10. batch_size = 1024
  11. k = 25
  12. num_classes = 10
  13. num_features = 28*28
  14. X = tf.placeholder(tf.float32,[None,num_features])
  15. y = tf.placeholder(tf.float32,[None,num_classes])
  16. kmeans = KMeans(inputs=X,num_clusters=k,distance_metric='cosine',use_mini_batch=True)
  17. # Build KMeans graph
  18. all_scores, cluster_idx, scores, cluster_centers_initialized,init_op, training_op = kmeans.training_graph()
  19. cluster_idx = cluster_idx[0]
  20. avg_distance = tf.reduce_mean(scores)
  21. # Initialize the variables (i.e. assign their default value)
  22. init_vars = tf.global_variables_initializer()
  23. sess = tf.Session()
  24. sess.run(init_vars, feed_dict={X: full_data_x})
  25. sess.run(init_op, feed_dict={X: full_data_x})
  26. # Training
  27. for i in range(1, num_steps + 1):
  28. _, d, idx = sess.run([training_op, avg_distance, cluster_idx],
  29. feed_dict={X: full_data_x})
  30. if i % 10 == 0 or i == 1:
  31. print("Step %i, Avg Distance: %f" % (i, d))
  32. counts = np.zeros(shape=(k, num_classes))
  33. for i in range(len(idx)):
  34. counts[idx[i]] += mnist.train.labels[i]
  35. # Assign the most frequent label to the centroid
  36. labels_map = [np.argmax(c) for c in counts]
  37. labels_map = tf.convert_to_tensor(labels_map)
  38. # Evaluation ops
  39. # Lookup: centroid_id -> label
  40. cluster_label = tf.nn.embedding_lookup(labels_map, cluster_idx)
  41. # Compute accuracy
  42. correct_prediction = tf.equal(cluster_label, tf.cast(tf.argmax(y, 1), tf.int32))
  43. accuracy_op = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  44. # Test Model
  45. test_x, test_y = mnist.test.images, mnist.test.labels
  46. print("Test Accuracy:", sess.run(accuracy_op, feed_dict={X: test_x, y: test_y}))

手写KMeans算法的更多相关文章

  1. 手写k-means算法

    作为聚类的代表算法,k-means本属于NP难问题,通过迭代优化的方式,可以求解出近似解. 伪代码如下: 1,算法部分 距离采用欧氏距离.参数默认值随意选的. import numpy as np d ...

  2. [纯C#实现]基于BP神经网络的中文手写识别算法

    效果展示 这不是OCR,有些人可能会觉得这东西会和OCR一样,直接进行整个字的识别就行,然而并不是. OCR是2维像素矩阵的像素数据.而手写识别不一样,手写可以把用户写字的笔画时间顺序,抽象成一个维度 ...

  3. 08.手写KNN算法测试

    导入库 import numpy as np from sklearn import datasets import matplotlib.pyplot as plt 导入数据 iris = data ...

  4. 手写-- K-means++

    1. K-means++原理 K均值聚类属于启发式方法,不能保证收敛到全局最优,初始中心的选择会直接影响聚类结果.K-means是随机选择样本点作为聚类中心,容易造成算法局部收敛或者需要较多迭代次数, ...

  5. 用C实现单隐层神经网络的训练和预测(手写BP算法)

    实验要求:•实现10以内的非负双精度浮点数加法,例如输入4.99和5.70,能够预测输出为10.69•使用Gprof测试代码热度 代码框架•随机初始化1000对数值在0~10之间的浮点数,保存在二维数 ...

  6. Javascript 手写 LRU 算法

    LRU 是 Least Recently Used 的缩写,即最近最少使用.作为一种经典的缓存策略,它的基本思想是长期不被使用的数据,在未来被用到的几率也不大,所以当新的数据进来时我们可以优先把这些数 ...

  7. 手写LRU算法

    import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends Link ...

  8. 手写hashmap算法

    /** * 01.自定义一个hashmap * 02.实现put增加键值对,实现key重复时替换key的值 * 03.重写toString方法,方便查看map中的键值对信息 * 04.实现get方法, ...

  9. 手写BP(反向传播)算法

    BP算法为深度学习中参数更新的重要角色,一般基于loss对参数的偏导进行更新. 一些根据均方误差,每层默认激活函数sigmoid(不同激活函数,则更新公式不一样) 假设网络如图所示: 则更新公式为: ...

随机推荐

  1. 《Fluid Engine Development》 学习笔记4-预测校正不可压缩SPH-PCISPH

    传统SPH方案的主要问题之一是时间步长限制.在原始的SPH中,我们首先从当前设置计算密度,使用EOS计算压强,应用压力梯度,然后运行时间积分.这个过程意味着只需要一定的压缩量就可以触发内核半径内的压力 ...

  2. Egret入门学习日记 --- 第十八篇(书中 8.5~8.7 节 内容)

    第十八篇(书中 8.5~8.7 节 内容) 其实语法篇,我感觉没必要写录入到日记里. 我也犹豫了好久,到底要不要录入. 这样,我先读一遍语法篇的所有内容,我觉得值得留下的,我就录入日记里. 不然像昨天 ...

  3. 20190923-基于Python3的RobotFramework的配置是初次使用

    因为最近改自动化框架在网上找了很多框架,发现RobotFramework不错,但是网上的资料很杂,现在将自己配置框架的学习笔记分享 Python配置RobotFramework的seleniumlib ...

  4. 高级UI-RecyclerView间隔线添加

    上文讲到了RecyclerView的简单使用,知道RecycleView是怎么使用的了,那么这一节将基于上一届的内容继续改进,在ListView中很轻松就能实现的间隔线,在RecycleView中也需 ...

  5. 说一说Unsafe魔法类

    这篇算是对 Unsafe 的一个总体概况,由于内容实在太多,后续会分开几篇文章对里面内容展开细讲 前言 Unsafe可以说是java的后门,类似西游记中的如来佛祖法力无边,Unsafe主要提供一些用于 ...

  6. nginx+flask02---概念

    概念理解 wsgiref模块是python提供的,用于测试和学习的简单的WSGI服务器模块. 这个模块监听8000端口(监听端口可以改变),把Http请求,根据WSGI协议,转换application ...

  7. In-App Purchase(iap)快速指南

      点击IOS IAP APP内支付 Java服务端代码直接跳转到示例点击直接跳转到示例 iap简介   在应用中内嵌Store,在iOS应用中使用Store Kit framework来实现In-A ...

  8. 【Docker】:docker安装ELK(logstash,elasticsearch,kibana)

    一:安装logstash 1.拉取镜像 docker pull logstash:5.6.11 2.创建目录 mkdir /docker/logstash cd /docker/logstash 3. ...

  9. Django打印出在数据库中执行的语句

    有时我们需要看models操作时对应的SQL语句, 可以用如下方法查看--- 在django project中的settings文件尾部添加如下代码 LOGGING = { 'version': 1, ...

  10. 前端开发 — HTML

    HTML HTML 超文本标记语言 HTML特征: 对换行和空格不敏感 空白折叠 1.1 HTML标签 标签也称为标记. 标签的种类: 1.双闭合标签 2.单闭合标签 1.1.1 head标签 met ...