基于word2vec 和 fast-pytorch-kmeans 的文本聚类实现,利用GPU加速提高聚类速度

文章目录

简介

本文使用text2vec模型,把文本转成向量。使用text2vec提供的训练好的模型权重进行文本编码,不重新训练word2vec模型。

直接用训练好的模型权重,方便又快捷

完整可运行代码如下:
https://github.com/JieShenAI/csdn/blob/main/machine_learning/kmeans_pytorch.ipynb

GPU加速

传统sklearn的TF-IDF文本转向量,在CPU上计算速度较慢。使用text2vec通过cuda加速,加快文本转向量的速度。

传统使用sklearn的kmeans聚类算法在CPU上计算,如遇到大批量的数据,计算耗时太长。

故本文使用fast-pytorch-kmeans 和 kmeans_pytorch包,基于pytorch在GPU上计算,提高聚类速度。

代码实现

装包

bash 复制代码
pip install fast-pytorch-kmeans text2vec
python 复制代码
import torch
import numpy as np

from text2vec import SentenceModel

不使用SentenceModel模型也可以,在 text2vec 中,还有很多其他的向量编码模型供选择。

文本编码模型

python 复制代码
embedder = SentenceModel()

异常情况说明,该模型需要从huggingface下载模型权重,目前被墙了。(请想办法解决,或者尝试其他的编码模型)

语料库如下:

python 复制代码
# Corpus with example sentences
corpus = [
    '花呗更改绑定银行卡',
    '我什么时候开通了花呗',
    'A man is eating food.',
    'A man is eating a piece of bread.',
    'The girl is carrying a baby.',
    'A man is riding a horse.',
    'A woman is playing violin.',
    'Two men pushed carts through the woods.',
    'A man is riding a white horse on an enclosed ground.',
]
corpus_embeddings = embedder.encode(corpus)
# numpy 转成 pytorch, 并转移到GPU显存中
corpus_embeddings = torch.from_numpy(corpus_embeddings).to('cuda')

如下图所示,编码的向量是768维;

python 复制代码
type(corpus_embeddings), corpus_embeddings.shape

kmeans

kmeans_pytorch vs fast-pytorch-kmeans:

在实验过程中,利用kmeans_pytorch 针对30万个词进行聚类的时候,发现显存炸了,程序崩溃退出。30万个词的词向量,占用显存还不到2G,但是运行kmeans_pytorch后,显存就炸了。

fast-pytorch-kmeans不存在上述显存崩溃的问题。本以为词向量很多会跑很长时间,但fast-pytorch-kmeans在非常短的时间内就完成了kmeans聚类。

后来一想也理解了,先开始在CPU跑花费了很长时间,这是因为CPU并行很差,需要逐个跑完。而在GPU里大量数据拼成一个矩阵,做一个减法,就可以算出批量节点和中心点的距离。

python 复制代码
# kmeans
# from kmeans_pytorch import kmeans
from fast_pytorch_kmeans import KMeans

num_class = 3 # 分类类别数
kmeans = KMeans(n_clusters=num_class, mode='euclidean', verbose=1)

# 模型预测结果
labels = kmeans.fit_predict(corpus_embeddings)

聚类程序运行如下:

used 2 iterations (0.3682s) to cluster 9 items into 3 clusters

模型中心点坐标:

python 复制代码
kmeans.centroids

聚类结果

python 复制代码
class_data = {
    i:[]
    for i in range(3)
}

for text,cls in zip(corpus, labels):
    class_data[cls.item()].append(text)

class_data

文本聚类结果如下:
0: 女
1:男
2: 花呗

kmeans 绘图函数

封装了KMeansPlot 绘图类,方便聚类结果可视化

python 复制代码
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

class KMeansPlot:

    def __init__(self, numClass=4, func_type='PCA'):
        if func_type == 'PCA':
            self.func_plot = PCA(n_components=2)
        elif func_type == 'TSNE':
            from sklearn.manifold import TSNE
            self.func_plot = TSNE(2)
        self.numClass = numClass

    def plot_cluster(self, result, pos, cluster_centers=None):
        plt.figure(2)
        Lab = [[] for i in range(self.numClass)]
        index = 0
        for labi in result:
            Lab[labi].append(index)
            index += 1
        color = ['oy', 'ob', 'og', 'cs', 'ms', 'bs', 'ks', 'ys', 'yv', 'mv', 'bv', 'kv', 'gv', 'y^', 'm^', 'b^', 'k^',
                    'g^'] * 3

        for i in range(self.numClass):
            x1 = []
            y1 = []
            for ind1 in pos[Lab[i]]:
                # print ind1
                try:
                    y1.append(ind1[1])
                    x1.append(ind1[0])
                except:
                    pass
            plt.plot(x1, y1, color[i])

        if cluster_centers is not None:
            #绘制初始中心点
            x1 = []
            y1 = []

            for ind1 in cluster_centers:
                try:
                    y1.append(ind1[1])
                    x1.append(ind1[0])
                except:
                    pass

            plt.plot(x1, y1, "rv") #绘制中心

        plt.show()

    def plot(self, weight, label, cluster_centers=None):
        pos = self.func_plot.fit_transform(weight)
        # 高维的中心点坐标,也经过降维处理
        cluster_centers = self.func_plot.fit_transform(cluster_centers)
        self.plot_cluster(list(label), pos, cluster_centers)

kmeans.centroids :是一个高维空间的中心点坐标,故在plot函数中,将其降维到2D平面上;

python 复制代码
k_plot = KMeansPlot(num_class)
k_plot.plot(
    corpus_embeddings.to('cpu'),
    labels.to('cpu'),
    kmeans.centroids.to('cpu')
)

完整可运行代码如下:
https://github.com/JieShenAI/csdn/blob/main/machine_learning/kmeans_pytorch.ipynb

相关资料参考

相关推荐
Be for thing14 小时前
PyTorch自动求导Autograd详解|requires_grad、backward、grad、梯度清零
pytorch·学习·1024程序员节
小毕超14 小时前
从推理到训练:Intel Ultra 核显 GPU 加速 YOLO 模型训练
pytorch·yolo·gpu·intel
摸鱼仙人~19 小时前
从 AI 应用开发到 GPU 计算软件:一份完整的 GPGPU、PyTorch、vLLM 与 AI Infra 学习路线
人工智能·pytorch·vllm
计算机毕业编程指导师2 天前
计算机毕设推荐:基于深度学习的动物图像识别方法研究(Python+Django+PyTorch)
pytorch·python·深度学习·计算机·毕业设计·课程设计·图像识别
zh路西法2 天前
【四足强化学习经典算法】(一):RMA——盲视运动控制与快速适应模块
pytorch·强化学习·1024程序员节·四足机器人·dagger·pyhon·rma
Be for thing3 天前
PyCharm安装与PyTorch项目配置|Jupyter Notebook与PyCharm使用对比
pytorch·学习·1024程序员节
zh路西法3 天前
【模型式强化学习】(二)PETS——从概率动力学模型到模型预测控制(MPC)
pytorch·python·强化学习·pe·mpc·ces·pets
段一凡-华北理工大学4 天前
高炉炼铁机器视觉与智能识别十八讲~系列文章17:实战案例:一个风口监控系统的完整搭建
人工智能·pytorch·深度学习·机器学习·计算机视觉·高炉风口监测系统
Yolanda_20224 天前
PyTorch 线性层nn.Linear底层数学原理
人工智能·pytorch·python
专注仿真4 天前
多智能体强化学习实战:从 Dec-POMDP 到 QMIX/MADDPG/MAPPO 的可运行 PyTorch 实现
人工智能·pytorch·python