传统机器学习 基于TF_IDF的文本聚类实现

news/2024/5/20 9:41:59 标签: 机器学习, 聚类, 人工智能

简介

使用sklearn基于TF_IDF算法,实现把文本变成向量。再使用sklearn的kmeans聚类算法进行文本聚类

个人观点:这是比较古老的技术了,文本转向量的效果不如如今的 text2vec 文本转向量好。
而且sklearn 不支持GPU加速,处理大量数据速度极慢。

实现

项目完整可运行代码:https://github.com/JieShenAI/csdn/blob/main/machine_learning/TF-IDF%20sklearn聚类.ipynb

import re
import random
import jieba
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfTransformer, TfidfVectorizer
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import gensim
from gensim.models import Word2Vec
from sklearn.preprocessing import scale
import multiprocessing

语料库如下

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.'
]

jieba 分词
jieba.add_word("花呗"),给jieba添加花呗, 不然 jieba 会把花呗拆分成'花', '呗'

分词模型,用起来还是有点麻烦

jieba.add_word("花呗")

def preprocess_text(content_lines, sentences):
    for line in content_lines:
        try:
            segs=jieba.lcut(line)
            segs = [v for v in segs if not str(v).isdigit()]#去数字
            segs = list(filter(lambda x:x.strip(), segs))   #去左右空格
            segs = list(filter(lambda x:len(x)>1, segs)) #长度为1的字符
            # segs = list(filter(lambda x:x not in stopwords, segs)) #去掉停用词
            sentences.append(" ".join(segs))
        except Exception:
            print(line)
            continue

sentences = []
# 处理语料,语料的处理结果存放在sentences
preprocess_text(corpus, sentences)

jieba 分词结果如下:
在这里插入图片描述

利用 TF_IDF 算法把分词结果转成向量

vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5)
#统计每个词语的tf-idf权值
transformer = TfidfTransformer()
# 第一个fit_transform是计算tf-idf 第二个fit_transform是将文本转为词频矩阵
tfidf = transformer.fit_transform(vectorizer.fit_transform(sentences))
# 获取词袋模型中的所有词语
word = vectorizer.get_feature_names_out()
# 将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重
weight = tfidf.toarray()
#查看特征大小
print ('Features length: ' + str(len(word)))

如下图所示,向量矩阵过于稀疏了,没有worc2vec编码的向量稠密。
在这里插入图片描述

编码的向量是33纬;
在这里插入图片描述

模型

为了方便使用,在JieKmeans类中封装了,kmeans聚类训练、预测和绘图功能。

from sklearn.decomposition import PCA

class JieKmeans:
    def __init__(self, numClass=4, n_components=10, func_type='PCA'):
        #这里也可以选择随机初始化init="random"

        self.PCA = PCA(n_components=n_components)
        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, newData):

        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 newData[Lab[i]]:
                # print ind1
                try:
                    y1.append(ind1[1])
                    x1.append(ind1[0])
                except:
                    pass
            plt.plot(x1, y1, color[i])

        #绘制初始中心点
        x1 = []
        y1 = []
        for ind1 in self.model.cluster_centers_:
            try:
                y1.append(ind1[1])
                x1.append(ind1[0])
            except:
                pass
        plt.plot(x1, y1, "rv") #绘制中心
        plt.show()


    def train(self, data):
        tmp = self.PCA.fit_transform(data)
        self.model = KMeans(
            n_clusters=self.numClass,
            max_iter=10000, init="k-means++", tol=1e-6)
        s = self.model.fit(tmp)
        print("聚类算法训练完成\n", s)



    def predict(self, data):
        t_data = self.PCA.fit_transform(data)
        result = list(self.model.predict(t_data))
        return result


    def plot(self, weight):
        t_data = self.PCA.fit_transform(weight)
        result = list(self.model.predict(t_data))
        plot_pos = self.func_plot.fit_transform(weight)
        self.plot_cluster(result, plot_pos)
net = JieKmeans(
    numClass=3, # 聚类类别
    n_components=5,
    func_type='PCA' # 绘图降纬方法
    )

net.train(weight)
# net.plot(weight)

聚类可视化

net.plot(weight)

在这里插入图片描述

如上图所示,上图的可视化显示聚类效果很好,但是由于TF-IDF文本转向量的效果不是很好,所以上述聚类出来的结果可能并不是我们想要的。

预测结果:

p = net.predict(weight)

class_data = {
    i:[]
    for i in range(3)
}

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

class_data

聚类结果如下:
在这里插入图片描述

进一步阅读

点击即可阅读,基于word2vec 和 kmeans_pytorch 的文件聚类实现,利用GPU加速提高聚类速度
该文使用text2vec通过cuda加速,加快文本转向量的速度。使用kmeans_pytorch包,基于pytorch在GPU上计算,提高聚类速度。
如下是其基于word2vec的聚类结果:


http://www.niftyadmin.cn/n/5433793.html

相关文章

NFTScan 正式上线 Blast NFTScan 浏览器和 NFT API 数据服务

2024 年 3 月 15 号,NFTScan 团队正式对外发布了 Blast NFTScan 浏览器,将为 Blast 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商,Blast 是继 Bitcoin、Ethereum、BNBChain、…

在集群模式下,Redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?

目录 一、分布式寻址算法 1. hash 算法 2. 一致性 hash 算法 3. Redis cluster 的 hash slot 算法 二、Redis cluster 的高可用与主备切换原理 1. 判断节点宕机 2. 从节点过滤 3. 从节点选举 4. 与哨兵比较 一、分布式寻址算法 hash 算法(大量缓存重建) 一致性 hash…

20个最佳ChatGPT社交媒体提示(2024年3月)

20 Best ChatGPT Prompts for Social Media (March 2024) 在当今快节奏的数字世界中,有效的沟通对于商业成功至关重要。ChatGPT可以成为您打造精准、吸引人且适合平台的内容的有力工具。以下是我们为您精心挑选的20个ChatGPT提示,适用于各种社交媒体平台…

C++初阶:模板初阶

目录 1. 模板的引入2. 函数模板与类模板2.1 函数模板2.2 模板调用方式2.3 函数模板与普通函数的调用优先性2.4 类模板2.5 类模板的构造函数,类模板声明与定义分离 1. 模板的引入 我们来看下面这几个函数: void swap(int& left, int& right) {int…

FFmpeg 常用命令汇总

​​​​​​经常用到ffmpeg做一些视频数据的处理转换等,用来做测试,今天总结了一下,参考了网上部分朋友的经验,一起在这里汇总了一下。 1、ffmpeg使用语法 命令格式: ffmpeg -i [输入文件名] [参数选项] -f [格…

c语言:于龙加

于龙加 任务描述 于龙同学设计了一个特别的加法规则,加法被重新定义了,我们称为于龙加。 两个非负整数的于龙加的意义是将两个整数按前后顺序连接合并形成一个新整数。 于龙想编程解决于龙加问题,可是对下面的程序他没有思路! …

本地用AIGC生成图像与视频

最近AI界最火的话题,当属Sora了。遗憾的是,Sora目前还没开源或提供模型下载,所以没法在本地跑起来。但是,业界有一些开源的图像与视频生成模型。虽然效果上还没那么惊艳,但还是值得我们体验与学习下的。 Stable Diffu…

时序分解 | Matlab实现GWO-CEEMDAN基于灰狼算法优化CEEMDAN时间序列信号分解

时序分解 | Matlab实现GWO-CEEMDAN基于灰狼算法优化CEEMDAN时间序列信号分解 目录 时序分解 | Matlab实现GWO-CEEMDAN基于灰狼算法优化CEEMDAN时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CEEMDAN方法的分解效果取决于白噪声幅值权重(Nstd)和噪声添…