楊 光, 賈焱鑫, 陳 翔,2, 許舒源
(1. 南通大學(xué) 信息科學(xué)技術(shù)學(xué)院, 江蘇 南通 226019; 2. 南京大學(xué) 計算機軟件新技術(shù)國家重點實驗室, 南京 210023)
科研開發(fā)人員經(jīng)常在其問答網(wǎng)站(例如Stack Overflow, 簡稱SO)上討論并解決技術(shù)開發(fā)過程中遇到的問題. 目前, SO中已積累了16 500 000個可以解決開發(fā)人員技術(shù)問題的問題帖及對應(yīng)的答案帖, 而用戶在如此海量的帖子中找到正確的解決方案有一定的困難. 因此, 對Stack Overflow網(wǎng)站的挖掘與分析已成為軟件倉庫挖掘領(lǐng)域的一個研究熱點. 例如: Shah等[1]通過建立邏輯回歸分類器為用戶提出的問題找出最優(yōu)答案并分析出答案的質(zhì)量; Mamykina等[2]分析了成功問答網(wǎng)站的設(shè)計特點; Openja等[3]從主題分析的角度對Stack Overflow網(wǎng)站上與軟件工程相關(guān)問題的帖子進(jìn)行了大規(guī)模實證研究.
為簡要描述SO的帖子內(nèi)容, 每個問題帖都標(biāo)有1~5個標(biāo)簽, 標(biāo)簽主要基于技術(shù)內(nèi)容對帖子進(jìn)行分類, 例如帖子是否與Android,Java或Hadoop等相關(guān). 目前, 網(wǎng)站使用用戶定義的標(biāo)簽對每個問題進(jìn)行分類, 但標(biāo)簽一般是在用戶發(fā)布問題時手工提供的, 這可能導(dǎo)致用戶提供了錯誤和不一致的標(biāo)簽, 例如一個用戶可能使用標(biāo)簽“iphone api”, 而另一個用戶可能使用“iphone sdk”, 雖然意圖相同(即帖子是相關(guān)的), 但由于帖子使用了不同標(biāo)簽, 所以不會被分在一組. 該問題導(dǎo)致了“標(biāo)簽爆炸”. 一般使用4%的標(biāo)簽即可完成90%的問題貼分類. 標(biāo)簽可能無法反映出問題的目的, 例如含有“Java”標(biāo)簽的問題只能確定該問題與Java語言有關(guān), 但無法確定該問題是與GUI開發(fā)相關(guān)還是與網(wǎng)絡(luò)問題相關(guān). 為解決上述問題, Barua等[4]提出了一種半自動方法, 該方法基于LDA(latent dirichlet allocation)[5], 其嘗試分析出主要的討論主題. 但研究表明, 不能僅分析開發(fā)人員所討論的主題, 在檢索開發(fā)人員的問題時, 也應(yīng)該考慮開發(fā)人員提問的原因. 了解帖子的提問目的可幫助開發(fā)人員在SO中找到相關(guān)的帖子, 并集成到IDE(integrated development environment)中[6]. Beyer等[7]提供了一個通用的分類方法, 給出了7種問題的目的類別: API_CHANGE,API_USAGE,CONCEPTUAL,DISCREPANCY,LEARNING,ERROES和REVIEW, 之后使用基于正則表達(dá)式和機器學(xué)習(xí)的方法對帖子進(jìn)行分類, 但基于正則表達(dá)式需要人工識別問題帖子中的短語模式, 因此存在模式手工提取困難的問題, 而傳統(tǒng)機器學(xué)習(xí)方法在預(yù)測性能方面則存在一定的瓶頸.
以提問目的對帖子進(jìn)行分類, 可以為分析SO上的帖子討論主題增加新的維度. 因此, 本文基于開發(fā)人員提問目的, 使用TextCNN和融合注意力機制的TextRNN方法對SO的帖子問題目的進(jìn)行分類, 并與4種傳統(tǒng)機器學(xué)習(xí)算法(樸素Bayes、K近鄰、 隨機森林和邏輯回歸)和文獻(xiàn)[7]提出的正則表達(dá)式方法為基準(zhǔn)方法進(jìn)行對比實驗. 實驗結(jié)果表明, 本文基于TextCNN和 融合注意力機制的TextRNN的深度學(xué)習(xí)模型對SO貼子問題目的上的分類性能在多數(shù)情況下都優(yōu)于對比方法.
隨著深度學(xué)習(xí)技術(shù)的迅速發(fā)展, 不同的深度神經(jīng)網(wǎng)絡(luò)模型逐漸被應(yīng)用到文本分類任務(wù)中, 其中最經(jīng)典的是TextCNN[8]和TextRNN[9]. 本文考察上述兩種深度文本分析算法在SO帖子問題目的分類上的預(yù)測性能. 本文方法的整體框架如圖1所示, 共分為3個階段: 數(shù)據(jù)預(yù)處理、 模型訓(xùn)練和模型驗證.
圖1 本文方法整體框架Fig.1 Overall framework of proposed method
卷積神經(jīng)網(wǎng)絡(luò)(convolutional neural network, CNN)的核心點在于可以捕捉局部相關(guān)性. 在文本分類任務(wù)中, 可利用CNN提取句子中類似N-gram的關(guān)鍵信息. 本文使用的卷積神經(jīng)網(wǎng)絡(luò)模型結(jié)構(gòu)如圖2所示, 該模型由輸入層、 卷積層、 池化層和全連接層構(gòu)成. TextCNN模型的輸入層需要輸入一個定長的文本序列, 本文輸入文本序列中各詞匯對應(yīng)的分布式表示(即詞向量). 由圖2可見, 輸入層(即最左邊矩陣)的每一行表示一個詞匯的詞向量, 維度為dim, 行數(shù)表示輸入訓(xùn)練的文本長度. 在卷積層中, 一般使用多個不同規(guī)模的濾波器, 在自然語言處理領(lǐng)域, 卷積核一般只進(jìn)行一維滑動, 即卷積核的寬度W與詞向量的維度dim等寬. 卷積核的高度H, 即窗口值, 可理解為N-gram模型中的N. 每個卷積核類似于一個可訓(xùn)練的濾波器, 提取輸入的部分特征, 然后將卷積結(jié)果經(jīng)過激活函數(shù)(即ReLU)處理后, 輸入到池化層. 池化層的輸入一般來源于上一個卷積層, 主要有如下作用: 1) 保留主要特征, 同時減少下一層的參數(shù)和計算量, 以防止過擬合問題; 2) 保持某種不變性. 在TextCNN模型的池化層中使用Max-pool, 既減少了模型的參數(shù), 又保證了在不定長的卷基層輸出上獲得一個定長的全連接層輸入. 全連接層的作用是分類器, TextCNN模型使用只有一層隱藏層的全連接網(wǎng)絡(luò), 相當(dāng)于將卷積與池化層提取的特征輸入到一個邏輯分類器中進(jìn)行分類.
圖2 TextCNN的網(wǎng)絡(luò)模型結(jié)構(gòu)Fig.2 Network model structure of TextCNN
盡管TextCNN在很多任務(wù)中性能較好, 但CNN中kernel_size視野的固定, 使其無法建模更長的序列信息, 且kernel_size的超參數(shù)調(diào)節(jié)也較繁瑣. CNN本質(zhì)是做文本的特征表達(dá), 而自然語言處理中更常用的是遞歸神經(jīng)網(wǎng)絡(luò)(RNN), 能更好地表達(dá)上下文信息. 在文本分類任務(wù)中, 本文使用基于雙向長短期記憶人工神經(jīng)網(wǎng)絡(luò)(LSTM)的TextRNN, 從某種意義上可理解為可捕獲變長且雙向的“N-gram”信息. TextRNN的結(jié)構(gòu)如圖3所示.
圖3 TextRNN的網(wǎng)絡(luò)模型結(jié)構(gòu)Fig.3 Network model structure of TextRNN
LSTM是一種特殊的RNN網(wǎng)絡(luò), 其設(shè)計目的是為了解決長依賴問題, 通過在RNN上加入門控實現(xiàn), 由3個門控制細(xì)胞狀態(tài), 分別為遺忘門、 輸入門和輸出門. 遺忘門通過查看ht-1和xt信息輸出一個[0,1]內(nèi)的向量, 該向量中的0,1值表示細(xì)胞狀態(tài)Ct-1中的哪些信息保留或丟棄, 0表示不保留, 1表示都保留, 用公式表示為
ft=σ(Wf·[ht-1,xt]+bf).
(1)
在輸入門處理前, 需決定給細(xì)胞狀態(tài)添加哪些新的信息.首先, 通過輸入門的操作決定更新哪些信息, 然后, 通過tanh層得到新的候選細(xì)胞信息, 這些信息可能會被更新到細(xì)胞信息中, 用公式表示為
it=σ(Wi·[ht-1,xt]+bi),
(2)
(3)
(4)
更新完細(xì)胞狀態(tài)后需要根據(jù)輸入的ht-1和xt判斷輸出細(xì)胞的哪些狀態(tài)特征, 輸出門將細(xì)胞狀態(tài)經(jīng)過tanh層得到一個[-1,1]內(nèi)的向量, 該向量與輸出門得到的判斷條件相乘即為最終該RNN單元的輸出, 用公式表示為
ot=σ(Wo[ht-1,xt]+bo),
(5)
ht=ot×tanh(Ct).
(6)
本文采用注意力機制[10]對TextRNN進(jìn)行優(yōu)化. 在對SO問題帖子進(jìn)行分類時主要依賴開發(fā)人員提供問題帖子的標(biāo)題和描述, 文本特征較稀疏, 注意力機制源于對人類視覺的研究, 使訓(xùn)練重點集中在輸入數(shù)據(jù)的相關(guān)部分而忽略無關(guān)部分.
下面對基于深度學(xué)習(xí)的SO帖子問題目的分類的有效性進(jìn)行實驗驗證.
考慮1 100個與Android相關(guān)的SO帖子, 該數(shù)據(jù)集由Beyer等[7]搜集并手動將這些帖子分類為7個問題類別. SO數(shù)據(jù)集中的特征簡稱及對應(yīng)的描述列于表1.
表1 SO數(shù)據(jù)集的特征簡稱及含義
由帖子的手動分類可知, 一些帖子可能同時屬于多個類別, 如圖4所示的帖子, 其同時被歸為API_USAGE和REVIEW. 因為短語“How can I”是API_USAGE類別的識別模式, 而短語“Is there a simpler way”是REVIEW類別的識別模式. 因此帖子問題目的分類是一個多標(biāo)簽分類問題(multi-label classification).
圖4 帖子問題目的分類實例Fig.4 Example of a post question purpose classification
本文使用二分類技術(shù), 將多標(biāo)簽分類轉(zhuǎn)換為二元分類問題: 為每個問題類別建立分類器模型, 以確定該帖子是否屬于該類別. 若將屬于該類別的帖子設(shè)為正例, 不屬于該類別的帖子設(shè)為反例, 則可根據(jù)真實類型與模型的預(yù)測類型組合, 將帖子劃分為真正例(true positive)、 假正例(false positive)、 真反例(true negative)和假反例(false negative), 并令TP,FP,TN和FN分別表示對應(yīng)的帖子數(shù).
準(zhǔn)確率表示在預(yù)測結(jié)果中, 正確分類的帖子數(shù)占所有帖子數(shù)的比例, 其計算公式為
(7)
F1指標(biāo)是查準(zhǔn)率和查全率的調(diào)和均值, 可對查準(zhǔn)率和查全率兩個指標(biāo)進(jìn)行有效的平衡, 其計算公式為
(8)
本文基于Pytorch框架設(shè)計基于TextCNN和基于融合注意力機制的TextRNN的SO帖子問題目的的分類方法. 首先需要對原始數(shù)據(jù)集進(jìn)行處理, 對原始數(shù)據(jù)去除〈code〉〈/code〉間的代碼片段, 去除html標(biāo)簽后, 再利用Porter Stemmer算法進(jìn)行詞干還原, 然后進(jìn)行分詞操作生成語料庫.
將數(shù)據(jù)集劃分為驗證集和測試集, 參考文獻(xiàn)[6]中的原始實驗設(shè)置, 將100個單獨用作測試的帖子分離出來, 為防止深度學(xué)習(xí)在訓(xùn)練時的過擬合問題, 將剩余的1 000個帖子按9∶1的比例進(jìn)一步劃分為訓(xùn)練集和驗證集. 對基準(zhǔn)方法的實現(xiàn), 基于正則表達(dá)式根據(jù)文獻(xiàn)[6]中的共享代碼進(jìn)行復(fù)現(xiàn), 基于機器學(xué)習(xí)的分類方法通過Sklearn進(jìn)行復(fù)現(xiàn).
本文將正則表達(dá)式分類方法用Reg表示, 將隨機森林方法用RF表示, 將線性回歸方法用LR表示, 將K近鄰方法用KNN表示, 將樸素Bayes方法用MNB表示, 將TextCNN方法用TCNN表示, 將TextRNN方法用TRNN表示. 有些類別(如API_CHANGE, LEARNING和REVIEW)存在明顯的類不平衡問題, 數(shù)據(jù)集的正負(fù)樣本百分?jǐn)?shù)列于表2. 本文采用隨機過采樣方法對3個類別進(jìn)行正負(fù)樣本不均衡問題處理, 將隨機重復(fù)正樣本, 直至正樣本數(shù)量與負(fù)樣本數(shù)量相同.
表2 數(shù)據(jù)集的正負(fù)樣本百分?jǐn)?shù)
實驗對比基準(zhǔn)方法采用基于隨機森林的機器學(xué)習(xí)方法、 正則表達(dá)式方法、 樸素Bayes方法、 邏輯回歸方法和K近鄰方法.
在機器學(xué)習(xí)的分類方法中, 先對文本進(jìn)行預(yù)處理, 然后計算帖子文本的tf-idf矩陣作為特征, 并使用各種機器學(xué)習(xí)的分類模型進(jìn)行分類測試. 深度學(xué)習(xí)模型的超參取值設(shè)置如下: Adam對應(yīng)的學(xué)習(xí)率設(shè)為0.001, SGD對應(yīng)的學(xué)習(xí)率設(shè)為0.1. 對于TextCNN模型, 卷積核的尺寸設(shè)為(2,3,4), 每種卷積核的數(shù)量設(shè)為256, Dropout設(shè)為0.5, 激活函數(shù)設(shè)為ReLU, 池化選擇設(shè)為1-max pooling, 詞向量維度設(shè)為100, batch_size設(shè)為128. 對于TextRNN模型, 使用兩層的LSTM, 第一層LSTM的hidden size設(shè)為256, 第二層的hidden size設(shè)為128, Dropout設(shè)為0.5, 激活函數(shù)設(shè)為ReLU, 詞向量維度設(shè)為300, batch_size設(shè)為32.
基于準(zhǔn)確率指標(biāo)和基于F1指標(biāo)的實驗結(jié)果分別列于表3和表4. 由表3和表4可見, 針對7個類別, 本文基于深度學(xué)習(xí)的問題貼分類方法, 在大部分情況下都優(yōu)于其他對比基準(zhǔn)方法. 宏觀上, 融合注意力機制的TextRNN方法優(yōu)于TextCNN方法. 其中在API_USAGE類別上, TextRNN方法的準(zhǔn)確率比隨機森林方法提高了9.64%, 比正則表達(dá)式方法提高了5.81%. 但在少數(shù)類別上的分類結(jié)果不如對比基準(zhǔn)方法, 在REVIEW類別上效果最差. 其性能不佳的原因為: 在100條測試集中REVIEW的正樣本數(shù)量僅11條, 而API_USAGE的正樣本數(shù)量有47條, 從而導(dǎo)致深度學(xué)習(xí)模型的分類性能并不理想.
表3 基于準(zhǔn)確率指標(biāo)的實驗結(jié)果
表4 基于F1指標(biāo)的實驗結(jié)果
針對優(yōu)化器選擇及是否采用預(yù)訓(xùn)練詞向量, 本文對模型性能的影響進(jìn)行了對比實驗. 在優(yōu)化器選擇上, 本文使用最常用的SGD優(yōu)化器和Adam優(yōu)化器; 在預(yù)訓(xùn)練詞向量上, 本文使用Glove預(yù)訓(xùn)練完的詞向量.
首先, 分析優(yōu)化器選擇對分類性能的影響, 對比結(jié)果列于表5和表6. 由表5和表6可見, 在準(zhǔn)確率指標(biāo)上, 使用Adam優(yōu)化器比使用SGD優(yōu)化器分類性能可平均提升1.59%; 在F1指標(biāo)上, 使用Adam優(yōu)化器比使用SGD優(yōu)化器分類性能可平均提升1.33%.
表5 優(yōu)化器選擇對TextCNN分類性能的影響
表6 優(yōu)化器選擇對TextRNN分類性能的影響
其次, 分析預(yù)訓(xùn)練詞向量對分類性能的影響, 對比結(jié)果列于表7和表8. 由表7和表8可見, 在準(zhǔn)確率指標(biāo)上, 使用Glove比使用隨機詞向量生成分類性能可平均提升0.3%; 在F1指標(biāo)上, 使用Glove比使用隨機詞向量生成分類性能可平均提升0.7%.
表7 是否采用預(yù)訓(xùn)練詞向量對TextCNN分類性能的影響
表8 是否采用預(yù)訓(xùn)練詞向量對TextRNN分類性能的影響
實驗結(jié)果表明, 采用基于深度學(xué)習(xí)的問題貼分類方法中, 使用Adam優(yōu)化器和Glove預(yù)訓(xùn)練完的詞向量可有效提高訓(xùn)練出模型的分類性能.
綜上所述, 本文基于深度學(xué)習(xí)的TextCNN和融合注意力機制的TextRNN, 提出了一種基于深度學(xué)習(xí)的SO問題帖分類方法, 并分析了該方法兩個設(shè)計要素對模型性能的影響. 與經(jīng)典基準(zhǔn)方法的對比結(jié)果驗證了該方法的有效性.