更新時間:2022年02月09日17時41分 來源:傳智教育 瀏覽次數(shù):
文本數(shù)據(jù)分析能夠有效幫助我們理解數(shù)據(jù)語料, 快速檢查出語料可能存在的問題, 并指導(dǎo)之后模型訓(xùn)練過程中一些超參數(shù)的選擇.
我們將基于真實的中文酒店評論語料來講解常用的幾種文本數(shù)據(jù)分析方法.
屬于二分類的中文情感分析語料, 該語料存放在"./cn_data"目錄下.其中train.tsv代表訓(xùn)練集, dev.tsv代表驗證集, 二者數(shù)據(jù)樣式相同.
該train.tsv數(shù)據(jù)樣式:
sentence label 早餐不好,服務(wù)不到位,晚餐無西餐,早餐晚餐相同,房間條件不好,餐廳不分吸煙區(qū).房間不分有無煙房. 0 去的時候 ,酒店大廳和餐廳在裝修,感覺大廳有點擠.由于餐廳裝修本來該享受的早飯,也沒有享受(他們是8點開始每個房間送,但是我時間來不及了)不過前臺服務(wù)員態(tài)度好! 1 有很長時間沒有在西藏大廈住了,以前去北京在這里住的較多。這次住進來發(fā)現(xiàn)換了液晶電視,但網(wǎng)絡(luò)不是很好,他們自己說是收費的原因造成的。其它還好。 1 非常好的地理位置,住的是豪華海景房,打開窗戶就可以看見棧橋和海景。記得很早以前也住過,現(xiàn)在重新裝修了??偟膩碚f比較滿意,以后還會住 1 交通很方便,房間小了一點,但是干凈整潔,很有香港的特色,性價比較高,推薦一下哦 1 酒店的裝修比較陳舊,房間的隔音,主要是衛(wèi)生間的隔音非常差,只能算是一般的 0 酒店有點舊,房間比較小,但酒店的位子不錯,就在海邊,可以直接去游泳。8樓的海景打開窗戶就是海。如果想住在熱鬧的地帶,這里不是一個很好的選擇,不過威海城市真的比較小,打車還是相當便宜的。晚上酒店門口出租車比較少。 1 位置很好,走路到文廟、清涼寺5分鐘都用不了,周邊公交車很多很方便,就是出租車不太愛去(老城區(qū)路窄愛堵車),因為是老賓館所以設(shè)施要陳舊些, 1 酒店設(shè)備一般,套房里臥室的不能上網(wǎng),要到客廳去。 0
train.tsv中的數(shù)據(jù)內(nèi)容共分為2列, 第一列數(shù)據(jù)代表具有感情色彩的評論文本; 第二列數(shù)據(jù), 0或1, 代表每條文本數(shù)據(jù)是積極或者消極的評論, 0代表消極, 1代表積極.
# 導(dǎo)入必備工具包 import seaborn as sns import pandas as pd import matplotlib.pyplot as plt # 設(shè)置顯示風(fēng)格 plt.style.use('fivethirtyeight') # 分別讀取訓(xùn)練tsv和驗證tsv train_data = pd.read_csv("./cn_data/train.tsv", sep="\t") valid_data = pd.read_csv("./cn_data/dev.tsv", sep="\t") # 獲得訓(xùn)練數(shù)據(jù)標簽數(shù)量分布 sns.countplot("label", data=train_data) plt.title("train_data") plt.show() # 獲取驗證數(shù)據(jù)標簽數(shù)量分布 sns.countplot("label", data=valid_data) plt.title("valid_data") plt.show()
注意:在深度學(xué)習(xí)模型評估中, 我們一般使用ACC作為評估指標, 若想將ACC的基線定義在50%左右, 則需要我們的正負樣本比例維持在1:1左右, 否則就要進行必要的數(shù)據(jù)增強或數(shù)據(jù)刪減. 上圖中訓(xùn)練和驗證集正負樣本都稍有不均衡, 可以進行一些數(shù)據(jù)增強。
# 在訓(xùn)練數(shù)據(jù)中添加新的句子長度列, 每個元素的值都是對應(yīng)的句子列的長度 train_data["sentence_length"] = list(map(lambda x: len(x), train_data["sentence"])) # 繪制句子長度列的數(shù)量分布圖 sns.countplot("sentence_length", data=train_data) # 主要關(guān)注count長度分布的縱坐標, 不需要繪制橫坐標, 橫坐標范圍通過dist圖進行查看 plt.xticks([]) plt.show() # 繪制dist長度分布圖 sns.distplot(train_data["sentence_length"]) # 主要關(guān)注dist長度分布橫坐標, 不需要繪制縱坐標 plt.yticks([]) plt.show() # 在驗證數(shù)據(jù)中添加新的句子長度列, 每個元素的值都是對應(yīng)的句子列的長度 valid_data["sentence_length"] = list(map(lambda x: len(x), valid_data["sentence"])) # 繪制句子長度列的數(shù)量分布圖 sns.countplot("sentence_length", data=valid_data) # 主要關(guān)注count長度分布的縱坐標, 不需要繪制橫坐標, 橫坐標范圍通過dist圖進行查看 plt.xticks([]) plt.show() # 繪制dist長度分布圖 sns.distplot(valid_data["sentence_length"]) # 主要關(guān)注dist長度分布橫坐標, 不需要繪制縱坐標 plt.yticks([]) plt.show()
通過繪制句子長度分布圖, 可以得知我們的語料中大部分句子長度的分布范圍, 因為模型的輸入要求為固定尺寸的張量,合理的長度范圍對之后進行句子截斷補齊(規(guī)范長度)起到關(guān)鍵的指導(dǎo)作用. 上圖中大部分句子長度的范圍大致為20-250之間。
# 繪制訓(xùn)練集長度分布的散點圖 sns.stripplot(y='sentence_length',x='label',data=train_data) plt.show() # 繪制驗證集長度分布的散點圖 sns.stripplot(y='sentence_length',x='label',data=valid_data) plt.show()
通過查看正負樣本長度散點圖, 可以有效定位異常點的出現(xiàn)位置, 幫助我們更準確進行人工語料審查. 上圖中在訓(xùn)練集正樣本中出現(xiàn)了異常點, 它的句子長度近3500左右, 需要我們?nèi)斯彶椤?/p>
# 導(dǎo)入jieba用于分詞 # 導(dǎo)入chain方法用于扁平化列表 import jieba from itertools import chain # 進行訓(xùn)練集的句子進行分詞, 并統(tǒng)計出不同詞匯的總數(shù) train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data["sentence"]))) print("訓(xùn)練集共包含不同詞匯總數(shù)為:", len(train_vocab)) # 進行驗證集的句子進行分詞, 并統(tǒng)計出不同詞匯的總數(shù) valid_vocab = set(chain(*map(lambda x: jieba.lcut(x), valid_data["sentence"]))) print("訓(xùn)練集共包含不同詞匯總數(shù)為:", len(valid_vocab))
輸出效果:
訓(xùn)練集共包含不同詞匯總數(shù)為: 12147 訓(xùn)練集共包含不同詞匯總數(shù)為: 6857
# 使用jieba中的詞性標注功能 import jieba.posseg as pseg def get_a_list(text): """用于獲取形容詞列表""" # 使用jieba的詞性標注方法切分文本,獲得具有詞性屬性flag和詞匯屬性word的對象, # 從而判斷flag是否為形容詞,來返回對應(yīng)的詞匯 r = [] for g in pseg.lcut(text): if g.flag == "a": r.append(g.word) return r # 導(dǎo)入繪制詞云的工具包 from wordcloud import WordCloud def get_word_cloud(keywords_list): # 實例化繪制詞云的類, 其中參數(shù)font_path是字體路徑, 為了能夠顯示中文, # max_words指詞云圖像最多顯示多少個詞, background_color為背景顏色 wordcloud = WordCloud(font_path="./SimHei.ttf", max_words=100, background_color="white") # 將傳入的列表轉(zhuǎn)化成詞云生成器需要的字符串形式 keywords_string = " ".join(keywords_list) # 生成詞云 wordcloud.generate(keywords_string) # 繪制圖像并顯示 plt.figure() plt.imshow(wordcloud, interpolation="bilinear") plt.axis("off") plt.show() # 獲得訓(xùn)練集上正樣本 p_train_data = train_data[train_data["label"]==1]["sentence"] # 對正樣本的每個句子的形容詞 train_p_a_vocab = chain(*map(lambda x: get_a_list(x), p_train_data)) #print(train_p_n_vocab) # 獲得訓(xùn)練集上負樣本 n_train_data = train_data[train_data["label"]==0]["sentence"] # 獲取負樣本的每個句子的形容詞 train_n_a_vocab = chain(*map(lambda x: get_a_list(x), n_train_data)) # 調(diào)用繪制詞云函數(shù) get_word_cloud(train_p_a_vocab) get_word_cloud(train_n_a_vocab)
驗證集正樣本形容詞詞云:
獲得驗證集上正負的樣本的形容詞詞云
# 獲得驗證集上正樣本 p_valid_data = valid_data[valid_data["label"]==1]["sentence"] # 對正樣本的每個句子的形容詞 valid_p_a_vocab = chain(*map(lambda x: get_a_list(x), p_valid_data)) #print(train_p_n_vocab) # 獲得驗證集上負樣本 n_valid_data = valid_data[valid_data["label"]==0]["sentence"] # 獲取負樣本的每個句子的形容詞 valid_n_a_vocab = chain(*map(lambda x: get_a_list(x), n_valid_data)) # 調(diào)用繪制詞云函數(shù) get_word_cloud(valid_p_a_vocab) get_word_cloud(valid_n_a_vocab)
根據(jù)高頻形容詞詞云顯示, 我們可以對當前語料質(zhì)量進行簡單評估, 同時對違反語料標簽含義的詞匯進行人工審查和修正, 來保證絕大多數(shù)語料符合訓(xùn)練標準. 上圖中的正樣本大多數(shù)是褒義詞, 而負樣本大多數(shù)是貶義詞, 基本符合要求, 但是負樣本詞云中也存在"便利"這樣的褒義詞, 因此可以人工進行審查。
什么是數(shù)據(jù)分析?數(shù)據(jù)分析有什么作用?