python可視化文本分析-分析Q群聊天記錄(一)

  • 2019 年 10 月 7 日
  • 筆記
  • 前一段時間就想做簡單的可視化文本分析玩,今天就花點時間先對整體班級的QQ群聊天資訊做一個簡單的分析。
  • 打算分兩步做,本文是最簡單的第一步過程
    • 1:分析整個聊天記錄的時間分配。並且用matplotlib展示出來。並把整個聊天的關鍵詞做成詞雲。
    • 2:融入snownlp情感分析,分析每個同學的詞雲分布,每個同學的發言次數情況,以及每個同學文本的情緒走勢以及展示。 等等
    • 總的來說就是先試試水,然後再做第二個。用到的庫有:jieba分詞,wordcloud詞雲,numpy數組,matplotlib可視化,snownlp(第二個),re正則(很重要)。這些用不到深入的東西,只用到很簡單的一小部分,都可以直接 pip install xxx。
  • 言歸正傳,下面說一下我的學習歷程:
  1. 首先,第一步就是導出群聊消息,再qq的資源管理器上選擇群可以 導出群消息記錄成txt文本。
  2. 要觀察聊天記錄的規則,了解 文本結構。能夠解析下列方框標註的內容很重要。

這部分主要的文本格式為:

2018-05-05 15:55:40 2班某某(1315426911)  2018-05-07 13:48:39 2XXX<[email protected]>  
  1. 下一步就需要 正則匹配獲取相應的內容。 這個地方的正則匹配規則也很簡單,因為格式固定. 但是我要分配各個聊天的時間,那麼就要匹配"15:55:40"這段話,可以重寫一個正則或者在原來的正則上添加,我選擇重寫正則,對於 正則取值前端時間簡單寫過取值兩個正則表達式為:
pattern=re.compile(r'(d*)-(d*)-(d*) .* .*')#匹配   資訊  pattern2=re.compile(r'(d+):(d+):d+')#匹配 15:55:40  
  1. 既然能取到上一步驟人說的話,那麼我們在下一步就需要對 數據去噪。那些數據會對結果有影響但是我們不需要的,這裡大致列了幾個(要注意的是文本換行符/n,每行無論是什麼都有一個換行符):
    • 空格消息
    • 紅包
    • 表情
    • 撤回的消息
    • 圖片
    • @全體成員
    • 個別群復讀機嚴重適當處理
    • 其他
  2. 這樣每次按行讀取,添加對應的次數和文本內容和水群次數。
  3. 製作聊天時間分布圖。使用matplotlib展示坐標的一些坑點已經解決。保存圖片到本地。
  4. 將各個文本合併生成班級主題詞雲。保存圖片到本地。
  5. 觀察詞雲的詞是否有不該出現的詞語,分析原因對數據進行 二次去噪。我當時就是因為第一次寫的正則沒有匹配"2018-05-07 13:48:39 2班[email protected]"導致詞雲出現一個同學的名字。。後來把正則改了就決絕了。你也可能會遇到特殊情況需要經常@某個人,,你可以自行處理。

程式碼開箱可用,你需要把你的文件名替換正確的路徑,還有要在同級目錄下創建img文件夾保存生成的兩張圖片。各種依賴環境很簡單,直接pip install xxx。 附上核心程式碼:

import re  import numpy as np  import matplotlib.pyplot as plt  ##繪圖庫  from wordcloud import WordCloud  import jieba.analyse  string="2018-05-05 15:55:40 2班某某(1315426911)"  pattern=re.compile(r'(d*)-(d*)-(d*) .* .*')  #匹配   2018-05-05 15:55:40 2班某某(1315426911) 有一個坑點就是2018-05-07 13:48:39 2XXX<[email protected]>這種格式  pattern2=re.compile(r'(d+):(d+):d+')#匹配 15:55:40  #pattern3=re.compile(r'(()(.*?)())')#匹配    2班某某(1315426911)相關內容  f = open('E:/text.txt', 'r', encoding='utf-8')  # 要進行分詞處理的文本文件 (統統按照utf8文件去處理,省得麻煩)  lines = f.readlines()  index=0  def getpicture(y):#matplotlib繪圖      x=[]      for i in range(0,24):          x.append(str(i)+':00-'+str(i+1)+':00')      Xi = np.array(x)      Yi = np.array(y)      plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤      plt.figure(figsize=(8, 6))  ##指定影像比例: 8:6      plt.subplots_adjust(bottom=0.2)      plt.scatter(Xi, Yi, color="red", label="times")      plt.xlabel("時間00:00—24:00")      plt.ylabel("發言次數/次")      plt.xticks(range(0,24),rotation=75,fontsize=10)#設置橫坐標顯示24次。      plt.yticks(range(0,1000,50))     # plt.legend(loc='lower right')  # 繪製圖例     # plt.show()      plt.savefig("img/hour.png",format='png')      plt.close()  def getciyun(value):      text=''      for i in range(0,24):          text+=str(value[i]['text'])      args=jieba.analyse.extract_tags(text,topK=80)      text=' '.join(args)      wc = WordCloud(background_color="white",                     width=1500, height=1000,                     min_font_size=40,                     font_path="simhei.ttf",                    # max_font_size=300,  # 設置字體最大值                     random_state=40,  # 設置有多少種隨機生成狀態,即有多少種配色方案                     )  # 字體這裡有個坑,一定要設這個參數。否則會顯示一堆小方框wc.font_path="simhei.ttf"   # 黑體      # wc.font_path="simhei.ttf"      my_wordcloud = wc.generate(text)        plt.imshow(my_wordcloud)      plt.axis("off")      plt.show()      wc.to_file('img/wordcloud.png')  def analysebyhour(lines):      value=[]      y=[]      index=0      for i in range(0,24):          value.append({})          value[i]['time']=0          value[i]['text']=''      for line in lines:          if line != "n" and line.strip() != "n" and line != None and not line.__contains__("撤回了"):             line = line.replace("[表情]", " ").replace("@全體成員", " ").replace("[表情]", " ").                  replace("[QQ紅包]我發了一個「專享紅包」,請使用新版手機QQ查收紅。", "").replace("n", " ").replace("[圖片]",'')             if(pattern.search(line)):#匹配到正確的對象                  date=pattern.search(line)                  hour=pattern2.search(line).group(1)                  #print(date.group(0),hour)                  value[int(hour)]['time']+=1                  index=hour             else:                 print(line)                 value[int(index)]['text']+=str(line)      for i in range(0,24):          print('time:',i,'time',value[i]['time'])          y.append(value[i]['time'])      getpicture(y)      getciyun(value)  analysebyhour(lines)  

然後兩張圖片就出來了:

  • 第一個點狀圖可以發現我們的聊天時間11:00-12:00突出,17:00-18:00突出,因為這個時間我們沒有課程在吃飯或者玩,有時候下午或者晚上或者其他的安排或者考試啥的可能會討論。而13:00-14:00這個點我們大部分在午休一般沒人聊天。但是醒了之後就會一直很活躍?。
  • 第二個詞雲可以看的出我們最近在聊啥,因為我的記錄是5月十幾才開始,記錄不足,準備找一份記錄足的做下一個研究。你可能通過詞雲發現我的其實還有挺大的不足就是QQ小冰沒有過濾掉。希望如果讀者有興趣嘗試可以處理一下。

通過這些簡單的文本分析感覺很有趣,有興趣等有時間把第二種也做出來,那種可能做起來比較麻煩一些。但是難道還是不大的。這些東西看似高深,其實了解api做起來很簡單。