码迷,mamicode.com
首页 > 编程语言 > 详细

【机器学习】k-means算法原理自实现

时间:2019-12-29 20:12:10      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:中心   otl   sha   continue   赋值   style   import   als   计数   

  1 import pandas as pd
  2 import numpy as np
  3 import matplotlib.pyplot   as plt
  4 from sklearn.cluster import KMeans # 导入k-means
  5 
  6 
  7 def build_data():
  8     """
  9     构建数据
 10     :return:data
 11     """
 12     # (1)加载数据
 13     data = pd.read_table("../day08/test.txt", sep="\t")
 14     print("data:\n", data)
 15     # print("data的数据类型\n", data.dtypes)
 16     # (2)转化为矩阵
 17     data = np.mat(data.values)
 18 
 19     # print("data:\n",data)
 20 
 21     return data
 22 
 23 
 24 def center_init(data, k):
 25     """
 26     初始化聚类中心
 27     :param data: 数据
 28     :param k: 聚类的类别数量
 29     :return: center
 30     """
 31     # 获取数据的行数
 32     index_num = data.shape[0]
 33     print(index_num)
 34     # 获取数据的列数
 35     columns_num = data.shape[1]
 36     print(columns_num)
 37     # for i in range(k):
 38     #     # 随机选择一行所有的数据作为一个中心
 39     #     # [low,high)
 40     #     r = np.random.randint(low=0, high=index_num, dtype=np.int32)
 41     #     print("r:\n",r)
 42     # 先初始化一个全为0 的聚类中心
 43     center = np.zeros(shape=(k, columns_num))
 44     # 设计列表来退出循环
 45     r_list = []
 46     # 设计一个计数器来 给聚类中心赋值
 47     i = 0
 48     while True:
 49         #   # 随机选择一行所有的数据作为一个中心
 50         #   # [low,high)
 51         r = np.random.randint(low=0, high=index_num, dtype=np.int32)
 52         if r not in r_list:
 53             # print("初始化为聚类中心")
 54             # 给聚类中心进行赋值
 55             center[i, :] = data[r, :]
 56             r_list.append(r)
 57             i += 1
 58         else:
 59             continue
 60         # 如果 随机选择了4个不同的r,那就退出循环
 61         if len(r_list) == k:
 62             break
 63 
 64     return center
 65 
 66 
 67 def distance(v1, v2):
 68     """
 69     计算距离
 70     :param v1:点1
 71     :param v2: 点2
 72     :return: 距离dist
 73     """
 74     # 法1
 75     # v1 是矩阵 将矩阵转化数组,再进行降为1维
 76     # v1 = v1.A[0]
 77     # print(v1)
 78     # sum_ = 0
 79     # for i in range(v1.shape[0]):
 80     #     sum_ += (v1[i] - v2[i]) ** 2
 81     # dist = np.sqrt(sum_)
 82     # print(dist)
 83     # 法2
 84     dist = np.sqrt(np.sum(np.power((v1 - v2), 2)))
 85     return dist
 86 
 87 
 88 def k_means_owns(data, k):
 89     """
 90     自实现k-means
 91     :param data: 需要的聚类的样本
 92     :param k: 聚类的类别数目
 93     :return: None
 94     """
 95 
 96     # 获取数据的行数
 97     index_num = data.shape[0]
 98 
 99     # 创建一个new_data 来保存每一个样本的最短距离与属于哪一个聚类中心的簇
100     new_data = np.zeros(shape=(index_num, 2))
101     print("new_data: \n", new_data)
102 
103     # (1)初始化聚类中心--随机在所有样本选择4行样本作为聚类中心
104     center = center_init(data, k)
105     print("center:\n", center)
106     flag = True
107     while flag:
108         flag = False
109         # (2) 计算每一个样本与每一个聚类中心的距离
110         for i in range(index_num):
111             min_dist = 10000000000000
112             min_index = -1
113             for j in range(k):
114                 # 计算距离
115                 dist = distance(data[i, :], center[j, :])
116                 print("dist:\n", dist)
117                 if dist < min_dist:
118                     min_dist = dist
119                     min_index = j
120             if new_data[i, 0] != min_index:
121                 flag = True
122                 new_data[i, :] = min_index, min_dist
123 
124         if flag:
125             # 求取各个簇的中心
126             for p in range(k):
127                 # p   --->0 1 2 3
128                 p_cluster = data[new_data[:, 0] == p, :]
129                 # print("第%d簇的样本:" % p)
130                 # print(p_cluster)
131                 # 计算新的聚类中心
132                 center[p, :] = p_cluster[:, 0].mean(), p_cluster[:, 1].mean()
133 
134     return new_data, center
135 
136 
137 def show_res_owns(data, new_data, center):
138     """
139     结果展示
140     :param data: 原数据
141     :param new_data: 记录属于哪一类别的数据
142     :param center: 聚类中心
143     :return: None
144     """
145     # 1、创建画布
146     plt.figure()
147     # 2、绘图
148     color_list = ["r", "g", "pink", "y"]
149     # 散点图
150     for i in range(data.shape[0]):
151         plt.scatter(data[i, 0], data[i, 1], c=color_list[int(new_data[i, 0])])
152 
153     # 绘制标注
154     plt.plot(center[:, 0], center[:, 1], "bx", markersize=12)
155     # 3、展示
156     plt.show()
157 
158 
159 def show_res(data, y_predict, center):
160     """
161     结果展示
162     :param data: 原数据
163     :param y_predict: 预测类别
164     :param center: 聚类中心
165     :return: None
166     """
167     # 1、创建画布
168     plt.figure()
169     # 2、绘图
170     color_list = ["r", "g", "pink", "y"]
171     # 散点图
172     for i in range(data.shape[0]):
173         plt.scatter(data[i, 0], data[i, 1], c=color_list[y_predict[i]])
174 
175     # 绘制标注
176     plt.plot(center[:, 0], center[:, 1], "bx", markersize=12)
177     # 3、展示
178     plt.show()
179 
180 
181 
182 def main():
183     """
184     主函数
185     :return: None
186     """
187     # 1、构建数据
188     data = build_data()
189     print("data:\n", data)
190 
191     # 2、自实现k-means
192     # (1)确定聚类的类别数目
193     k = 4
194     new_data, center = k_means_owns(data, k)
195     #
196     print("new_data:\n", new_data)
197     print("最终的聚类中心:\n", center)
198 
199     # 3、结果展示
200     show_res_owns(data, new_data, center)
201 
202 
203     # 使用sklearn中的kmeans来实现聚类
204     # 1、创建算法实例
205     # km = KMeans(n_clusters=k)
206     # # 2、训练数据
207     # km.fit(data)
208     # # 3、进行预测
209     # y_predict = km.predict(data)
210     # # 获取聚类中心
211     # center = km.cluster_centers_
212     #
213     # print("预测值:\n",y_predict)
214     # print("center:\n",center)
215 
216     # 进行结果展示
217     # show_res(data,y_predict,center)
218 
219 
220 if __name__ == __main__:
221     main()

【机器学习】k-means算法原理自实现

标签:中心   otl   sha   continue   赋值   style   import   als   计数   

原文地址:https://www.cnblogs.com/Tree0108/p/12116152.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!