Python——KMeans(k均值聚类)实战(附详细代码与注解)
开始之前
各位朋友周末好,今天博主小码将开车≥Ö‿Ö≤为大家用代码实战讲解KMeans聚类,请大家坐稳了≡(▔﹏▔)≡。作为机器学习的十大经典算法之一,聚类的相关现实应用非常之广,如图像分割,文本分类、市场分割等,相关的干货知识请查阅相关资料,接下来小码直接带大家撸代码了。
前提准备
为了让各位乘客有良好的乘车体验,请准备如下:
Jupyter notebook
火狐浏览器或谷歌浏览器
win7或win10电脑一台
具备图像处理的知识如numpy,opencv等
啦啦啦!当然还有不怕吃苦的钻研精神。≧◠◡◠≦✌
需求分析
对我国某视频APP的小镇中国区潜在会员数分布用KMeans进行聚类,通过聚类结果知道会员的分布情况。先给大家看下最后的效果图:
本代码所需的图片我将通过网盘给大家
一、读取中国地图
import numpy as np import cv2 import matplotlib.pyplot as plt img_china = cv2.imread('../china.png') #读取中国地图图片 plt.imshow(img_china,cmap="gray") #对图像进行处理,并显示其格式 plt.xticks([]),plt.yticks([]) #去除x、y轴 plt.show()
【注】plt.imshow()函数负责对图像进行处理,并显示其格式,但是不能显示,其后跟着plt.show()才能显示出来。
效果:
二、特征提取过程
【注】用画图软件加入黑色散点(潜在会员数)(这个不需要大家做,已经用ps做好,保存在china_people.png),另存为china_people.png。
import numpy as np import cv2 import matplotlib.pyplot as plt img_china = cv2.imread('../china2thresh.png') #读取上一步已经处理好的图片,这里无需看第一步的代码,第一步只是告诉如何处理图片,这里china2thresh.png就是第一步处理完成用于第二步的图片 img_china_people = cv2.imread('../china_people.png') #读取用ps处理的会员分布散点图 img_people = img_china - img_china_people #此处用到图像相减,两幅图像间对应像素的灰度值相减,用于目标检测 r_img_china = cv2.split(img_china)[0] #图像颜色通道的分离,看不懂没关系,毕竟这不是重点 r_img_people = cv2.split(img_people)[2] cv2.imwrite('../people.png',r_img_people) #把处理后的img_people,存入people.png print("中国大陆面积(像素数):",np.unique(r_img_china,return_counts = True)[1][1]) #获取中国地图像素大小 print("小镇中国区潜在会员数(像素数):",np.unique(r_img_people,return_counts = True)[1][1]) #获取小镇中国区潜在会员数像素大小 psw = [] #把三张图片img_china、img_china_people、img_people放入数组句柄中,当然我们最后需要的是img_people psw.append(("china",img_china)) psw.append(("china + people",img_china_people)) psw.append(("people",img_people)) plot_number = len(psw) cols = 3 rows = plot_number/cols + 1 for index in range(plot_number): plt.subplot(rows,cols,index + 1) plt.imshow(psw[index][1],cmap = "gray") plt.title(psw[index][0],fontsize =15 ) plt.xticks([]),plt.yticks([]) plt.show() #用for循环按要求打印出如下效果
【注】subplot(n,m,x)解释:建立一个mn的绘图区域,然后分别在其x=1,2,3,4,…区域绘制图像*
三、从people图中提取样本作为KMeans的训练集
print(r_img_people.shape) #打印出people图的像素范围 X = np.argwhere(r_img_people) print(X.shape) #小镇中国区潜在会员数分布,样本数为78739,为二维数组 X[0:10] #打印出前10个样本所在像素点位置
效果:
四、训练KMeans模型(重点)
from sklearn.cluster import KMeans #从sklearn导入KMeans算法 import copy k = 72 #指定簇的数目,KMeans聚类需要预先指定要聚成多少类 y_KMeans = KMeans(n_clusters=k, random_state=9) #KMeans函数调用、传参 y_pred = y_KMeans.fit_predict(X) #预测样本分别属于哪些类 print(y_pred) src_img_china = copy.deepcopy(img_china) r_src_img_china = cv2.split(src_img_china)[0] #根据索引赋值 for i in range(len(X)): index = X[i] src_img_china[index[0]][index[1]] = [y_pred[i]*(255/k), (255/3 + y_pred[i]*(255/k))%255, 255*2/3+(y_pred[i]*(255/k))]
【注】random_state的作用是控制随机状态,固定random_state为某个固定的值后,每次构建的模型都是相同的、生成的数据是相同的、每次拆分的结果也是相同的。可以把它理解为控制变量。
效果:
五、可视化结果
cv2.imwrite("../result.png",cv2.cvtColor(src_img_china , cv2.COLOR_RGB2BGR)) #颜色转换,了解即可 plt.imshow(src_img_china) plt.xticks([]),plt.yticks([]) plt.show() plt.scatter(X[:,1],X[:,0],c=y_pred) #把预测的结果用散点图画出 plt.xticks([]),plt.yticks([]) ax = plt.gca() ax.invert_yaxis() plt.show()
效果:
六、输出结果
num_pix_china = np.unique(r_img_china, return_counts=True)[1][1] print('中国大陆面积(像素数):', num_pix_china) num_all_people = np.unique(r_img_people, return_counts=True)[1][1] print('小镇中国区潜在会员数(像素数):', num_all_people) print('每个簇的中心点坐标(像素坐标):', y_KMeans.cluster_centers_) print('每个簇的潜在会员数(簇内像素数):',np.unique(y_pred, return_counts=True)) #每个簇内到簇中心距离列表: # print(X.shape) # print(y_pred.shape) dic_result_xy = {} dic_result = {} for i in range(y_pred.shape[0]): if y_pred[i] not in dic_result: dic_result_xy[y_pred[i]]=[] dic_result[y_pred[i]]=[] dic_result_xy[y_pred[i]].append(X[i]) # print('jjjjjjjjj',i,X[i][0]-y_KMeans.cluster_centers_[y_pred[i]][0]) # print('kkkkkkkkk',i,X[i][1]-y_KMeans.cluster_centers_[y_pred[i]][1]) dic_result[y_pred[i]].append( np.sqrt( np.square(X[i][0]-y_KMeans.cluster_centers_[y_pred[i]][0])\ + np.square(X[i][1]-y_KMeans.cluster_centers_[y_pred[i]][1]))) if i%5000 == 0: print('计算到第{}个循环'.format(i)) # print(dic_result_xy[0][:10]) # print(dic_result[0]) #每个簇内到簇中心平均距离: tmp = [] for i in range(k): tmp.append(np.mean(dic_result[i])) print('每个簇簇内所有点到簇中心平均距离(像素距离):') print(tmp) tmp = [] for i in range(k): tmp.append(np.median(dic_result[i])) print('每个簇簇内所有点到簇中心中位数距离(像素距离):') print(tmp) tmp = [] for i in range(k): tmp.append(max(dic_result[i])) print('每个簇簇内所有点到簇中心最远距离(像素距离):') print(tmp) print(np.mean(tmp)) actual_china = 9083674#纯陆地9,083,674平方千米 pix2km = np.sqrt(actual_china/num_pix_china) print('最终:', np.mean(tmp)*pix2km,'km')
由于打印结果比较多,小码就不把打印结果截图贴上来了,还请大家动手实践,有问题可找我交流,谢谢大家!
【附】:百度网盘图片链接
提取码:4wc4
- 点赞 16
- 收藏
- 分享
- 文章举报
- [置顶] 【二分-kMeans算法】二分K均值聚类分析与Python代码实现
- kmeans聚类的简介和代码(python)
- 机器学习项目实战--贷款申请利润最大化(附详细讲解,python代码)
- k-均值聚类Python代码实现
- Python实现kMeans(k均值聚类)
- 机器学习-K均值聚类(python3代码实现)
- kmeans 聚类 --- (代码为: 博客数据聚类) (python )
- kmeans聚类的简介和代码(python)
- Python实现kMeans(k均值聚类)
- Python 1行代码实现文本分类(实战笔记),含代码详细说明及运行结果
- 机器学习实战 - 第十章 K-均值聚类 代码报错整理
- 我的kmeans聚类 python代码
- Python 1行代码实现文本分类(实战笔记),含代码详细说明及运行结果
- 2019经典版:Python爬虫验证码破解实战(内有详细代码)
- 【Python数据挖掘课程】三.Kmeans聚类代码实现、作业及优化
- 机器学习算法与Python实践之(五)k均值聚类(k-means)
- Python执行代码的实际操作的五个步骤详细介绍
- [python] 基于k-means和tfidf的文本聚类代码简单实现
- Python数据挖掘课程 三.Kmeans聚类代码实现、作业及优化
- 500G python web、爬虫、数据分析、机器学习、大数据、前端实战项目视频代码免费分享