机器学习:Kmeans聚类算法总结及GPU配置加速demo

  • Kmeans算法介绍
  • 版本1:利用sklearn的kmeans算法,CPU上跑
  • 版本2:利用网上的kmeans算法实现,GPU上跑
  • 版本3:利用Pytorch的kmeans包实现,GPU上跑
  • 相关资料

Kmeans算法介绍


  • 算法简介

    • 该算法是一种贪心策略,初始化时随机选取N个质心,不断迭代,让周围元素到质心的误差累积和最小,从而找到质心或者说对应的簇。
  • 核心步骤

    • 先得到待分类的大量数据(多维向量)
    • 初步尝试得到最佳的分类簇数量
    • 根据最佳簇数量和随机起点作聚类
    • 得到最佳簇划分的码矢,将其编制成固定顺序
    • 计算得到个别数据对应的index,即码矢的索引序号
    • 码矢的集合组成码本
  • 评判指标

    • 簇内相似度高,即被分类到某一簇的样本,离簇的距离足够小
    • 簇间相似度低,即每个簇的差距较大,能表征更多信息

下面Python代码实践总结如下,分别布置在CPU和GPU上。

版本1:利用sklearn的kmeans算法,CPU上跑


  • 好处

    • 快速调用机器学习库,sklearn
    • 适合进行码本训练和简单分类任务
  • 劣势

    • 问题当数据量大时,迭代速度较慢
  • 参考链接:here

import module_kmeans
dir_in = r"/home/work/codebook_train_data/"
# module_kmeans.sf_kmeans(dir_in)

对应的调用脚本文件:sf_kmeans.py,内部代码如下:

# -*- coding: utf-8 -*-
import sys
import os
import wave
from scipy.io import wavfile
import numpy as npimport pandas as pd
import matplotlib.pyplot as plt# error
# from sklearn.datasets.samples_generator import make_blobs
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeansdef sf_kmeans(path):data = pd.read_csv(path + 'sf_taylor.csv')X = data.iloc[:, 0:16]  # get low 16 values# X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)# plt.scatter(X[:, 0], X[:, 1])# plt.close()# plt.figure()max_range = 1025wcss = []for i in range(1, max_range):kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)kmeans.fit(X)wcss.append(kmeans.inertia_)plt.figure()plt.grid(linestyle='-.')plt.title('Elbow Method')plt.xlabel('Number of clusters')plt.ylabel('WCSS')plt.plot(range(1, max_range), wcss)plt.show()plt.figure()kmeans = KMeans(n_clusters=4, init='k-means++', max_iter=300, n_init=10, random_state=0)pred_y = kmeans.fit_predict(X)plt.grid(linestyle='-.')plt.scatter(X[:, 0], X[:, 1])plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red')plt.show()print(kmeans.labels_)print(kmeans.cluster_centers_)print('done!')

版本2:利用网上的kmeans算法实现,GPU上跑


  • 好处:

    • 能解决迭代速度问题
  • 劣势:
    • 随之而来的问题是,该算法实现精度较差
    • 无法达到与本地CPU跑的sklearn的kmeans算法效果
  • 参考链接:here
import torch
import time
from tqdm import tqdm
import pandas as pd# import pdb # for debug
# pdb.set_trace()class KMEANS:def __init__(self, n_clusters=20, max_iter=None, verbose=True,device = torch.device("cuda")):self.n_cluster = n_clusters # n_clusters > 0self.n_clusters = n_clustersself.labels = Noneself.dists = None  # shape: [x.shape[0],n_cluster]self.centers = Noneself.variation = torch.Tensor([float("Inf")]).to(device)self.verbose = verboseself.started = Falseself.representative_samples = Noneself.max_iter = max_iterself.count = 0self.device = devicedef fit(self, x):# 随机选择初始中心点,想更快的收敛速度可以借鉴sklearn中的kmeans++初始化方法init_row = torch.randint(0, x.shape[0], (self.n_clusters,)).to(self.device)init_points = x[init_row]self.centers = init_pointswhile True:# 聚类标记self.nearest_center(x)# 更新中心点self.update_center(x)if self.verbose:print(self.variation, torch.argmin(self.dists, (0)))if torch.abs(self.variation) < 1e-3 and self.max_iter is None:breakelif self.max_iter is not None and self.count == self.max_iter:breakself.count += 1self.representative_sample()def nearest_center(self, x):labels = torch.empty((x.shape[0],)).long().to(self.device)dists = torch.empty((0, self.n_clusters)).to(self.device)for i, sample in enumerate(x):dist = torch.sum(torch.mul(sample - self.centers, sample - self.centers), (1))labels[i] = torch.argmin(dist)dists = torch.cat([dists, dist.unsqueeze(0)], (0))self.labels = labelsif self.started:self.variation = torch.sum(self.dists - dists)self.dists = distsself.started = Truedef update_center(self, x):centers = torch.empty((0, x.shape[1])).to(self.device)for i in range(self.n_clusters):mask = self.labels == icluster_samples = x[mask]centers = torch.cat([centers, torch.mean(cluster_samples, (0)).unsqueeze(0)], (0))self.centers = centersdef representative_sample(self):# 查找距离中心点最近的样本,作为聚类的代表样本,更加直观self.representative_samples = torch.argmin(self.dists, (0))def sf_kmeans(matrix,device):max_range = 4wcss = []gpu_speeds = []print(matrix.shape)print(matrix)print('\n')for i in tqdm(range(1, max_range + 1)):
#         print('%d'%(i), end='\r')a = time.time()kmeans = KMEANS(n_clusters=i, max_iter=None, verbose=False, device=device)kmeans.fit(matrix)
#         wcss.append(kmeans.inertia_)wcss.append(torch.sum(kmeans.dists))
#         print(torch.sum(kmeans.dists) / k)
#         print(kmeans.variation)b = time.time()speed = (b - a) / kmeans.countgpu_speeds.append(speed)print(kmeans.centers)print(kmeans.dists)print(torch.sum(kmeans.dists))print('\n')#     plt.figure()plt.grid(linestyle='-.')plt.title('Elbow Method')plt.xlabel('Number of clusters')plt.ylabel('WCSS')plt.plot(range(max_range), wcss)plt.show()plt.figure()l2, = plt.plot(range(max_range), gpu_speeds, color='g',label = "GPU")plt.xlabel("num_features")plt.ylabel("speed(s/iter)")plt.title("Speed with cuda")plt.legend(handles = [l2], labels = ['GPU'], loc='best')def choose_device(cuda=False):if cuda:device = torch.device("cuda:0")else:device = torch.device("cpu")return deviceif __name__ == "__main__":import matplotlib.pyplot as pltdir_in = r"/home/work/codebook_train_data/"
#     data = pd.read_csv(dir_in + 'sf_taylor.csv')
#     df = data.iloc[:, 0:16]  # get low 16 values
#     print(df.dtypes)
#     print(type(data))
#     np_data = df.valuesdata = pd.read_csv(dir_in + 'Mall_Customers.csv')np_data = data.iloc[1 : 6, [3, 4]].valuesdevice = choose_device(True)matrix = torch.from_numpy(np_data).to(device)matrix = matrix.float()
#     matrix = torch.rand((10000, 10)).to(device)sf_kmeans(matrix, device)

版本3:利用Pytorch的kmeans包实现,GPU上跑


调用Pytorch现成的kmeans包,进行修改。

  • 好处:

    • 能解决迭代速度问题
    • 达到与sklearn相同的精度结果
  • package name:kmeans-pytorch

  • 相关资料:ref1

  • 相关资料:ref2

  • 以下代码含画图及对比

!pip install kmeans-pytorch
import torch
import numpy as np
import time
# from tqdm import tqdm
import pandas as pd
# from kmeans_pytorch import kmeans
from module_pytorch_kmeans import kmeans
import matplotlib.pyplot as pltdef choose_device(cuda=False):if cuda:device = torch.device("cuda:0")else:device = torch.device("cpu")return devicedef sf_kmeans(matrix,device, dims):max_range = 40wcss = []gpu_speeds = []#     print(matrix.shape)
#     print(matrix)
#     print('\n')# data
#     data_size, dims, num_clusters = 1000, 2, 3
#     x = np.random.randn(data_size, dims) / 6
#     x = torch.from_numpy(x)for n_clusters in range(2, max_range + 1):a = time.time()# kmeanscluster_ids_x, cluster_centers, iters = kmeans(X=matrix, num_clusters=n_clusters, distance='euclidean', tqdm_flag=False, device=torch.device('cuda:0'))
#         iter_limit=500, #         print(cluster_ids_x)
#         print(cluster_centers)
#         print('\n')dists = torch.empty((0, dims)).to(device)for i, sample in enumerate(matrix):# 0按行追加扩展, 1按列追加扩展id = cluster_ids_x[i]dist = torch.mul(sample.to(device) - cluster_centers[id].to(device), sample - cluster_centers[id].to(device))dists = torch.cat([dists, dist.unsqueeze(0)], (0))print(torch.sum(dists))
#         print('\r{}'.format(torch.sum(dists)), end='')wcss.append(torch.sum(dists))b = time.time()speed = (b - a) / itersgpu_speeds.append(speed)
#         print('\n')#     print(wcss)
#     print(gpu_speeds)#     plt.figure()plt.grid(linestyle='-.')plt.title('Elbow Method')plt.xlabel('Number of clusters')plt.ylabel('WCSS')plt.plot(range(max_range - 1), wcss)plt.show()plt.figure()l2, = plt.plot(range(max_range - 1), gpu_speeds, color='g',label = "GPU")plt.xlabel("num_features")plt.ylabel("speed(s/iter)")plt.title("Speed with cuda")plt.legend(handles = [l2], labels = ['GPU'], loc='best')if __name__ == "__main__":dir_in = r"/home/work/codebook_train_data/"data = pd.read_csv(dir_in + 'sf_large.csv')dims = 8df = data.iloc[:, 0:dims]  # get low 16 values
#     print(df.dtypes)
#     print(type(data))np_data = df.values#     data = pd.read_csv(dir_in + 'Mall_Customers.csv')
#     np_data = data.iloc[1 : 6, [3, 4]].valuesdevice = choose_device(True)matrix = torch.from_numpy(np_data).to(device)matrix = matrix.float()#     matrix = torch.rand((10000, 10)).to(device)sf_kmeans(matrix, device, dims)

输出提示如下:

tensor(3.3288e+08, device=‘cuda:0’)
tensor(2.3872e+08, device=‘cuda:0’)
tensor(1.9115e+08, device=‘cuda:0’)
tensor(1.6357e+08, device=‘cuda:0’)
tensor(1.4616e+08, device=‘cuda:0’)

相关资料


  1. K-means Clustering Python Example
  2. K-means(K均值)
  3. scikit-learn之kmeans应用及问题
  4. 用scikit-learn学习K-Means聚类
  5. kmcuda: GPU加速 Kmeans
  6. In-depth Intuition of K-Means Clustering Algorithm in Machine Learning

机器学习:Kmeans聚类算法总结及GPU配置加速demo相关推荐

  1. 基于经典的机器学习k-means聚类算法实现对三通道图片的压缩操作

    https://www.toutiao.com/a6573221465104056846/ 压缩图片的原理 k-means算法实现图像的压缩是k-means聚类算法的一个经典的应用,它把一个彩色图压缩 ...

  2. 机器学习——Kmeans聚类算法

    目录 简介 手肘法 手肘法核心思想 轮廓系数 代码举例1 代码举例2 实例 简介 K均值聚类算法是先随机选取K个对象作为初始的聚类中心.然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距 ...

  3. 机器学习——K-Means聚类算法及其应用

    概括 首先说一下聚类,多用于机器学习中的无监督学习,通俗来说是将具有相似性的数据分为多类(在相似的基础上收集数据来分类).由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其 ...

  4. 基于GPU的K-Means聚类算法

    聚类是信息检索.数据挖掘中的一类重要技术,是分析数据并从中发现有用信息的一种有效手段.它将数据对象分组成为多个类或簇,使得在同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别很大.作为统计学的 ...

  5. 离线轻量级大数据平台Spark之MLib机器学习库聚类算法KMeans实例

    1.KMeans算法 所谓聚类问题,就是给定一个元素集合D,其中每个元素具有n个可观察属性,使用某种算法将D划分成k个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的元素相异度尽可能高.其 ...

  6. 【白话机器学习】算法理论+实战之K-Means聚类算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...

  7. [Python从零到壹] 十三.机器学习之聚类算法四万字总结全网首发(K-Means、BIRCH、树状聚类、MeanShift)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  8. 机器学习十大经典算法之K-Means聚类算法

    聚类介绍 聚类在机器学习,数据挖掘,模式识别,图像分析以及生物信息等领域有广泛的应用.聚类是把相似的对象通过静态分类的方法分成不同的组别或者更多的子集(subset),这样让在同一个子集中的成员对象都 ...

  9. 【机器学习】使用scikitLearn对数据进行聚类:Kmeans聚类算法及聚类效果评估

    无监督学习: [机器学习]使用scikitLearn对数据进行聚类:Kmeans聚类算法的应用及密度聚类DBSCAN [机器学习]使用scikitLearn对数据进行聚类:高斯聚类GaussianMi ...

  10. 机器学习7—聚类算法之K-means算法

    K-均值算法(K-means) 前言 聚类算法模型 常见的聚类算法 一.K-means算法描述 二.示例说明K-means算法流程 三.K-means算法中Kmean()函数说明 四.K-means算 ...

最新文章

  1. raid5数据恢复成功案例
  2. Dockerfile多阶段构建
  3. SpringBoot项目中对mysql数据库进行定时备份为sql文件的实现思路
  4. 超级简单的mysql主从数据库配置攻略以及错误处理
  5. Queue)) 类,msdn上的一篇文章,便于查看
  6. superset出现unhashable type: ‘dict‘
  7. [剑指offer]面试题第[59-1]题[Leetcode][第239题][JAVA][滑动窗口的最大值][单调队列][优先队列]
  8. 測试新浪微博@小冰 为代码机器人的一些方法
  9. less-postcss
  10. 1 企业实战(3) Redis服务部署和配置详解 (资源)
  11. 小游戏一键跳转小程序任意页面
  12. 小美赛之matlab笔记
  13. 【笔记】知行合一王阳明:1472~1529
  14. LaTeX 多语言支持
  15. 网页编程入门应该首先学些什么
  16. 使用物理学和领域知识的神经网络的无标签监督解读(上)
  17. vue常用之“定义全局变量constants”
  18. 阿里云-邮件推送 配置 购买域名 配置域名
  19. Altium Designer生成Gerber文件的设置(嘉立创建议 )
  20. iOS10、11自定义左滑菜单项背景图片

热门文章

  1. 俞扬 新书_哇,太好了...新书
  2. 【日常】DES加密算法python实现_以密码编码学与网络安全——原理与实践(第六版)课后习题3.11为例
  3. 【从Northwind学习数据库】汇总查询
  4. 一个废物大学生对于视频爬取的小小的总结
  5. USB无线网卡的Linux驱动移植
  6. autocad.net-图片打印合成
  7. cruzer php sandisk 闪迪u盘量产工具_SanDisk Cruzer Micro(U盘量产工具) V1.0 电脑版
  8. 【转】将安全证书导入到java的cacerts证书库
  9. MQTT代理服务器的选择
  10. teraterm 执行sql命令_捆绑你的操作(windows tera term高阶用法之并行处理)