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()