在現實生活中,有時候我們可能得到一大堆無標簽文本,這時候可能需要對文本進行聚類挖掘,找出熱點問題是什么,
文本聚類
第一步:資料讀取
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 ,聚類 ,聚類結果和原始分詞拼接,繪制高頻詞云圖,統計各類高頻詞,
即可得到熱點問題是什么,

大家好,我是余登武,電氣工程的計算機萌新,寫博文不容易,如果你覺得本文對你有用,請點個贊支持下,謝謝,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/1534.html
標籤:其他
