基于聚类算法的文本热点问题挖掘算例实现(文本聚类)

在现实生活中,有时候我们可能得到一大堆无标签文本,这时候可能需要对文本进行聚类挖掘,找出热点问题是什么。

文本聚类

第一步:数据读取

import pandas as pd
import re
import jieba

csv='95598处理后.csv'
file_txt=pd.read_csv(csv, header=0,encoding='gbk')#
file_txt=file_txt.dropna()#删除空值[4229 rows x 2 columns]
print(file_txt.head())

其他格式数据读取方法
现实生活中 文本数据有可能不是表格,是txt文件。
txt读取方法链接:
python读取txt文件(多种方法)

这里简单演示下读取一个文件夹下的所有txt文件数据.
原始文件夹 一张图两个txt


import os
import re

#首先定义规则,如我们需要把所有的txt文件

pattern=re.compile(r'.+\.txt')

for root ,dirs,files in os.walk(r'C:\Users\Shineion\Desktop\新建文件夹'):
    for name in files:

        file_path=os.path.join(root,name)#包含路径的文件
        matching=pattern.search(file_path)#匹配txt
        if matching:
            command_line =file_path.replace('/', '\\') #\\ 变 \
            print(command_line)
            f = open(command_line,encoding='utf')
            data = f.readlines()  # 直接将文件中按行读到list里,效果与方法2一样
            f.close()  # 关
            print(data)  # 返回list

简单演示啦下,读取出来的数据有换行符\n。需要的时候正则化处理就可以啦。

如果是Word文字读取,参考链接
python自动化办公:word篇。职场高手不是梦。

第二步:预处理函数
去除数字字母 和停用词
停用词链接:nlp 中文停用词数据集

# 定义删除除字母,数字,汉字以外的所有符号的函数
def remove_punctuation(line):
    line = str(line)
    if line.strip() == '':
        return ''
    rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")
    line = rule.sub('', line)
    return line

#停用词
def stopwordslist(filepath):
    stopwords = [line.strip() for line in open(filepath, 'r', encoding='gbk').readlines()]
    return stopwords

第三步:数据预处理实现
其中clean_review代表去除数字字母后的文本,cut_review代表去除停用词后的文本

# 加载停用词
stopwords = stopwordslist("停用词.txt")

#去除标点符号
file_txt['clean_review']=file_txt['ACCEPT_CONTENT'].apply(remove_punctuation)
#去除停用词
file_txt['cut_review']=file_txt['clean_review'].apply(lambda x:" ".join([w for w in list(jieba.cut(x)) if w not in stopwords]))
print(file_txt.head())

第四步:tf-idf

from sklearn.feature_extraction.text import CountVectorizer#词袋
from sklearn.feature_extraction.text import TfidfTransformer#tfidf
#词袋计数
count_vect = CountVectorizer()
X = count_vect.fit_transform(file_txt['cut_review'])

#tf-idf
tfidf_transformer = TfidfTransformer()
X_tfidf = tfidf_transformer.fit_transform(X)
print(X_tfidf)

第五步:手肘法选择聚类中心数
①手肘法
手肘法的核心指标是SSE(sum of the squared errors,误差平方和),

其中,Ci是第i个簇,p是Ci中的样本点,mi是Ci的质心(Ci中所有样本的均值),SSE是所有样本的聚类误差,代表了聚类效果的好坏。

手肘法的核心思想是:随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小。并且,当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当k到达真实聚类数时,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的真实聚类数。当然,这也是该方法被称为手肘法的原因。

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# '利用SSE选择k'
SSE = []  # 存放每次结果的误差平方和
for k in range(1, 9):
    estimator = KMeans(n_clusters=k)  # 构造聚类器
    estimator.fit(X_tfidf)
    SSE.append(estimator.inertia_)
X = range(1, 9)
plt.xlabel('k')
plt.ylabel('SSE')
plt.plot(X, SSE, 'o-')
plt.show()

从图中看到,肘部并未明显出现,这时候我们应该扩大更大数值如范围1到10。 其实我们也隐约的知道 肘部数据为7或者8.我们就取7吧。

第六步:聚类实现

# K均值聚类
model_kmeans = KMeans(n_clusters=7,random_state=1)  # 创建聚类模型对象
model_kmeans.fit(X_tfidf)  # 训练模型
# 聚类结果
cluster_labels = model_kmeans.labels_  # 聚类标签结果
print(cluster_labels)

第七步:结果拼接汇总
将聚类得到的标签和原始数据进行拼接.
我这里选择的是将分词结果和标签进行拼接。
可以拼接更多的数据,如再加上原文。

#结果拼接
labels=pd.DataFrame(cluster_labels,columns=['标签'])

shuju=pd.concat([file_txt['cut_review'],labels],axis=1)
print(shuju)

第八步:统计每类词汇

cat_desc = dict()
biaoqian_values=[0,1,2,3,4,5,6]#聚类标签
for i in biaoqian_values:
    text = shuju.loc[shuju['标签'] == i, 'cut_review']
    text = (' '.join(map(str, text))).split(' ')
    cat_desc[i] = text
print(cat_desc[2])#打印2类词汇

第九步:绘制高频词词云

#词云图
#查看词云
from collections import Counter
from wordcloud import WordCloud
def generate_wordcloud(tup):
    wordcloud = WordCloud(background_color='white',
                          font_path='simhei.ttf',
                          max_words=50, max_font_size=40,
                          random_state=42
                          ).generate(str(tup))
    return wordcloud
fig, axes = plt.subplots(4, 2, figsize=(30, 38))

k = 0
for i in range(4):
    for j in range(2):
        most10 = Counter(cat_desc[k]).most_common(10)#10个高频词
        ax = axes[i, j]
        ax.imshow(generate_wordcloud(most10), interpolation="bilinear")
        ax.axis('off')
        ax.set_title("{} Top 10".format(k), fontsize=30)

        if k<6:
           k += 1

plt.show()

因为只有7个类别,我的画布是(4,2)所以最后一幅图画2次
if k<6:
k += 1
本文给出的原始文本数据 都属于电力工单,所以高频词云图你看起来决定很相似。如果给出的原始文本数据多种多样,饮食,体育,那结果显示就不一样的。

第10步:统计各类词频
如果你不想结果以词云图显示,想以文本格式显示。

from collections import Counter
for i in range(7):
    most10 = Counter(cat_desc[i]).most_common(10)
    print('第{0}类前10个高频词'.format(i),most10)

总结
本文给出的文本数据例子可能不是太好。各类之间高度相似。
思路:分词 ,tf-idf ,聚类 ,聚类结果和原始分词拼接,绘制高频词云图,统计各类高频词。
即可得到热点问题是什么。

在这里插入图片描述
大家好,我是余登武。电气工程的计算机萌新。写博文不容易。如果你觉得本文对你有用,请点个赞支持下,谢谢。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kobeyu652453/article/details/108446391
今日推荐