張天倫,陳 榮,楊 溪,祝宏玉
1(大連海事大學 信息科學技術學院,遼寧 大連 116026)
2(深圳大學 計算機與軟件學院,廣東 深圳 518060)
在軟件系統開發領域里,Bug修復[1]是一個十分關鍵的環節.近幾年,隨著軟件工程項目的規模與復雜度的提升,在軟件開發過程中,不可避免地會出現大量的 Bug,為了系統可以正常運行,修復這些 Bug是十分必要的;同時,修復這些Bug的任務量也是非常艱巨的.對于軟件系統的開發人員而言,在修復Bug時,最常用的輔助工具就是Bug報告[2].Bug報告是以文本的形式來描述Bug細節的數據,并且根據任務的不同,這些數據被標上不同的標簽.但是Bug報告的質量良莠不齊,如果人工地辨別這些Bug報告的質量,無疑又為軟件開發帶來了沉重的工作量.所以近幾年,很多研究者研究如何將Bug報告進行自動分類,其中,Antoniol等人[3]利用文本挖掘技術來對Bug報告進行分類,將Bug報告數據分成需即時處理的Bug和非即時處理的Bug,他們所使用的技術是決策樹、對率回歸以及樸素貝葉斯等方法.Menzies等人[4]利用規則學習技術將Bug報告分成嚴重Bug和非嚴重Bug.Tian等人[5]通過構建一個基于機器學習的預測框架來預測Bug報告的優先級,在這個框架中,他們主要考慮到6個因素:時序、內容、作者、嚴重程度、產生原因以及相關的Bug.除此之外,還有學者對Bug報告的質量進行分類.Feng等人[6]通過提取Bug報告的特征,來對Bug報告進行高質量和低質量的區分,并且將預測得到的信息提交給軟件開發者.為了降低Bug的冗余度,Runeson等人[7]基于信息檢索技術提出一種計算Bug報告相似性的方法.類似的,Sun等人[8]提出一種多特征的信息檢索模型,其目的也是為了計算Bug報告之間的相似度.近些年,更多的學者關注于 Bug報告數據集的類別不平衡問題,其中,Lamkanfi等人[9]通過人工選擇的方法來補充數據集,解決數據集的類別不平衡問題,但是人工選擇的方法局限性很大,同時也不適合于實際的工作;Yang等人[10]利用解決不平衡問題的策略來處理Bug報告分類問題,即隨機欠采樣(random under-sampling,簡稱RUS)、隨機過采樣(random over-sampling,簡稱ROS)和合成少數類過采樣(synthetic minority over-sampling,簡稱SMOTE)方法,這些方法在解決不平衡問題時,其效率明顯優于人工選擇的方法.
本文的關注點也是自動分類Bug報告,但是我們更加關注于Bug報告分類中存在的一些問題.
首先,在Bug報告數據集里,不同類別的樣本的數量不同,而且通常情況下,樣本數量之間的差異會造成較大的不平衡度.如果一個數據集的不平衡度較大,那么通過這個數據集訓練得到的分類模型的性能就會受到不良的影響.這主要是因為在訓練過程中,不平衡的數據集會引導分類器更加側重于對多數類樣例的識別,在更嚴重的情況下,少數類的樣例會被當做噪音點處理.
為了解決 Bug報告中數據不平衡的問題,我們引入了基于代價的分類器訓練策略.傳統上的分類器的優化求解目標主要是最大化分類結果的精確度,而基于代價的分類器訓練策略則是最小化分類器因錯誤分類而產生的代價.具體地,不同類別的樣例被錯誤分類的代價應該不同,一些較易被分類的樣例應該有較小的錯誤代價,而那些較難被分類的樣例應該有比較大的錯誤分類代價.在最小化整體的錯誤分類代價時,就會使得分類器更加關注代價大的樣例的分類情況.因為傳統的分類器模型默認所有樣例的分類代價是一樣的,所以基于代價的分類器訓練方法是對傳統方法的一個擴展.
我們選用的分類器模型是極速學習機(extreme learning machine,簡稱ELM).該方法由Huang等人[11]提出,因為其訓練方法的高效性,目前被普遍用于模式識別領域[12].同時,為了解決上面提到的數據不平衡問題,我們用基于代價的分類器訓練方法來訓練ELM模型,訓練得到的模型被稱為代價敏感的ELM模型.
Bug報告分類中存在的第 2個問題是:在數據集里,被標記的樣本量不充足.傳統的分類器大都是通過有監督算法進行訓練的,這就要求數據集里的樣本既有條件屬性也要有與之對應的標簽屬性.可是,給樣本指定正確的標簽需要大量的精細的人工標注工作.通常情況下,人工給數據標注類別屬性是繁重且耗時的,所以為了解決這個問題,本文提出一種可以自動標注標簽的半監督學習方法.該方法主要利用弱分類器對未知標簽的數據進行類別標定,然后結合模糊度[13]這一指標選擇不確定性小的數據來擴充原有的有標簽的數據集.
在 Bug報告分類中,第 3個問題是:數據集的樣本總量不充足.在訓練分類器時,往往需要充足的訓練數據.當訓練數據不充分時,會導致訓練得到的分類器出現嚴重的過擬合現象.過擬合現象主要表現為:分類器在訓練集上的分類效果良好,可是在測試時或者在實際工作中,其分類效果很不理想.這主要是因為訓練樣本容量少導致分類器對數據的統計規律學習得不充分,最終使其泛化能力弱,不能對訓練集以外的數據做出正確的判別.
為了解決這個問題,我們提出一種樣本遷移[14]的方法,即用其他 Bug數據集里的樣本來補充數據量不充足的數據集的樣本容量.自然地,如何選取樣本來補充數據集,這是一個十分關鍵的問題.在我們的工作中,我們仍舊利用第二個問題里的方法.即先在原數據集上訓練得到一個弱分類器,然后用弱分類器對被遷移的樣本進行分類,得到分類結果后,結合模糊度,選擇模糊度小的樣本來補充原始的數據集.在這個過程中,需要注意,不同的數據集的樣本維度可能不同.為了統一維度,我們提出使用受限玻爾茲曼機(restricted Boltzmann machines,簡稱RBM)[15]來對不同數據集的樣本進行編碼,即將不同數據集里的樣本編碼成統一維度的數據.這樣做使得我們的方法具有更加廣泛的適用性.注意到,用來自不同分布的樣例來補充訓練集合,這個方法的可行性已經在文獻[16]得到證明,并且在我們的實驗中會進一步被驗證.
綜上所述,本文的貢獻點主要有 3個方面:(1) 針對Bug報告中的類別不平衡問題,我們將基于代價的分類器訓練方法引入到Bug報告分類問題里,并且使用ELM作為基本的分類模型;(2) 針對Bug報告中被標記的樣本數量不充足的問題,我們將基于模糊度的半監督方法引入到 Bug報告分類問題里,通過擴充有標簽的樣本容量來增強分類效果;(3) 針對Bug報告中數據集樣本總量不充足的問題,我們將基于RBM和模糊度的樣本遷移方法引入到Bug報告分類問題里,通過擴充訓練集總樣本容量來避免分類器出現過擬合的現象.
本文第1節介紹本文涉及到的相關背景知識.第2節詳細介紹本文提出來的方法.第3節展示本文的相關實驗.第4節對本文的工作進行總結與展望.
在這一節中,我們將詳細介紹本文主體方法所涉及到的背景知識.這些背景知識主要分為兩個部分:第 1個是ELM的訓練策略;第2個是RBM的學習方法.
本文主要關注的是對 Bug報告數據集的分類問題.我們選用的是基于神經網絡的分類器.神經網絡是一種非線性的函數模型,該模型通過調節網絡參數,可以擬合輸入到輸出的映射關系.近幾年,神經網絡在模式識別領域里取得了很多令人矚目的成果[17-19],尤其在自然語言處理的工作里,基于神經網絡的方法要明顯優于其他方法的效果[20].自動識別Bug報告的類別,是一種關于自然語言的類別識別工作,所以我們選用神經網絡作為分類模型.
按照訓練方式劃分,神經網絡可以被分為兩種類型:第1種是基于迭代優化的方法[21]來調整網絡的參數;第2種是基于隨機賦權的方法[22,23]來學習網絡的參數.其中,ELM作為一種隨機賦權網絡模型,在近幾年廣泛受到關注.ELM主要的優點是訓練方式高效快捷,并且在大多數領域里,其性能要優于或者等于迭代尋優算法訓練出來的網絡.接下來,我們詳細介紹ELM的參數學習過程.
ELM模型是一個單隱層的前饋神經網絡,如圖1所示.其中,I是網絡的輸入層(由nus個節點組成),H是網絡的隱層(由ncc個節點組成),O是網絡的輸出層(由ns個節點組成).輸入層和隱層之間的權重α∈?nus×ncc是網絡輸入層權重,隱層和輸出層之間的權重β∈?ncc×ns是網絡的輸出層權重,為了增加網絡模型的線性表達能力,在隱層加入了偏置矩陣B=[b1,b2,…,bn]T,其中,bi=(b1,…,bncc)T.為了提高網絡的非線性表達能力,隱層的每一個單元節點需要被非線性函數作用,這里稱這個函數為激活函數,一般地,該函數選擇的是sigmoid函數,即


Fig.1 Feedforward neural network model with single hidden layer圖1 單隱層前饋神經網絡模型
ELM的訓練方法是有監督的方法,因而在訓練過程中需要有標簽的數據集S.在S中,條件屬性矩陣用X表示,決策屬性矩陣用T表示,這兩個矩陣的形式如下所示.

其中,n代表數據集S中的樣本總個數;X中每一行是一個nus維的樣本向量;T中每一行是一個ns維的標簽向量,該向量用one-hot形式表示,且ns等于數據集里的類別個數.
在實際的分類工作中,I接收輸入矩陣X,經前向傳播依次得到H的輸出H∈?n×ncc和O的輸出Y∈?n×ns.

其中,X是已知的,α和B是被隨機賦值的,只有β一個是未知量,也就是需要優化求解的網絡參數.優化的目標是最小化網絡輸出Y和期望輸出T之間的距離:

β可以用下面的等式求解.

很明顯,通過上式求解β是一個最小二乘問題.其中,為了更一般化地定義上式的求解過程,可以求H的廣義逆,即Moore-Penrose逆.
接下來將介紹本文所涉及到的另一個數學模型,即RBM.RBM是一個概率圖模型[24],其結構如圖2所示.可以看出,RBM是一個無向二分圖模型.其中,v=(v1,v2,...,vnv)是可見層(由nv個節點構成),h=(h1,h2,...,hnh)是隱藏層(由nh個節點構成).RBM在本文里的主要作用是將可見層的數據編碼成隱藏層的表達形式.由于RBM的訓練機制采用的是無監督的方法,所以訓練數據集S={v1,v2,…,vN}里的樣本vi不需要標簽屬性,N是樣本個數.

Fig.2 Network structure of RBM圖2 RBM網絡結構
可見層和隱藏層的條件概率公式可由下面的公式來表達.

其中,σ的函數形式是 sigmoid函數.在上面的式子中,a=(a1,a2,...,anv)是可見層偏置,b=(b1,b2,...,bnh)是隱藏層偏置,W=[wi,j]nh×nv是RBM的網絡權重.a,b和W是需要學習的參數θ.給定訓練集合S,優化目標是求解下式的極大似然.


可以看出,因為∑v的存在,上式的計算復雜度為O(2nv+nh).為了簡化計算復雜度,可以采用 Gibbs采樣[24]的方法,經過t次采樣后,上式可以通過下面的式子近似求解.

具體地,在本文里,我們采用Hinton等人[25]提出來的對比散度(contrastive divergence,簡稱 CD)算法來優化RBM模型的參數,優化過程如算法1所示.
算法1.RBM的訓練算法.

在這一節中,我們將詳細介紹我們提出來的方法,并且將這個新的方法用于解決 Bug報告分類中普遍存在的3個問題:第1個問題是數據類別不平衡問題,第2個是訓練集里被標記的數據不充足的問題,第3個是數據集之間的樣本遷移問題.
ELM 是一種隨機賦權網絡模型,和其他神經網絡一樣,是一種非線性函數.在分類問題里,ELM 將條件屬性域里的樣本映射為決策屬性域里的類別標簽.在這一點上,ELM和其他分類器一樣,都是通過學習樣例到標簽之間的映射關系來進行分類工作.ELM的具體學習過程在第1節里已經詳細介紹,這個學習過程的優化目標就是最小化實際輸出和期望輸出之間的距離,這個距離通常是二者之間的歐氏距離.在分類問題中,網絡的期望輸出是樣例的類別標簽(一般將其表達成 one-hot形式的向量),通過最小化網絡的實際輸出向量與期望輸出向量之間的歐氏距離,來學習得到網絡的參數.
可是,有一個問題需要注意:在分類問題里,每一類的樣例被錯誤分類的代價應該是不同的,比如在不平衡數據集里,多數類樣例因為樣本個數多,所以更容易被正確分類,而少數類樣例則更容易被錯誤分類,所以一個多數類樣例被錯誤分類的代價應該小于一個少數類樣例被錯誤分類的代價.但是在ELM以及大多數分類器的前提假設里,都默認每個類別的樣例被錯誤分類的代價是一樣的.
本文主要是解決Bug報告的嚴重性分類問題.在實際工作中,嚴重的Bug需要被即時處理,不嚴重的Bug可以被延時處理.在自動分類Bug時,就需要準確預測Bug報告的嚴重程度,將嚴重的Bug識別出來,即時地提交開發人員處理.但是在大多數Bug報告數據集里,嚴重的Bug樣例個數要明顯多于不嚴重的Bug樣例個數,因此Bug報告數據集通常都是類別不平衡的數據集.這樣導致分類器易將不嚴重Bug誤報成嚴重Bug,降低了分類器對嚴重 Bug的識別準確率.為此,我們對 ELM 模型在分類問題上進行擴展,得到一種考慮到錯誤代價的分類模型.因此,我們引入代價敏感的ELM分類模型[26].
為了構建代價敏感的ELM分類模型,首先需要構造一個錯誤分類的代價矩陣D,即

在這個矩陣里,di,j代表第i類樣例被錯誤分到第j類的代價大小,很明顯地,di,j等于零,也就是第i類樣例被正確分類時所產生的代價是零.我們用ci代表第i類樣例被錯誤分類的代價,ci可以用下面的公式求得.

假設數據集里的類別個數一共是ns,那么通過等式(7),所有類別的樣例被錯誤分類的代價可以被集合Cost表示:Cost=(c1,c2,…,cns).
通過引入代價矩陣,代價敏感的ELM將原始的ELM擴展成了一個考慮到錯誤分類代價的分類模型.在優化過程中,代價敏感的 ELM 將優化目標擴展成為一個帶有代價權重的歐氏距離之和.為了表示這個優化目標,首先將訓練集里的樣例按照類別分組,同上,這里假設類別個數為ns,每一組樣例同屬于一個類別,這個組可以被表示為Xi,被分組后的數據集可以被表示為可以由下面的公式求出.,其對應的標簽矩陣為T,對應的隱層矩陣H

代價敏感的ELM的優化目標是最小化分類錯誤代價,通過上面給出的一些符號化定義,這個優化目標可以被表示為


和第1節介紹的ELM參數優化求解方法一樣,這里的矩陣求逆可通過Moore-Penrose廣義逆來求解得到.
在本文所要解決的Bug報告分類問題中,數據集都是二分類問題,其中多數類是嚴重的Bug報告,少數類是不嚴重的Bug報告.通常,這兩類之間會存在很大的不平衡度[9,10],因此,我們在這里提出來用代價敏感的ELM來分類 Bug報告數據集里的樣例,通過給少數類樣例比較大的錯誤分類代價,給多數類樣例比較小的錯誤分類代價,并且最小化錯誤分類的總代價,來自動地解決Bug報告數據集在分類過程里存在的類別不平衡問題.
其中,所有數據集上的代價矩陣是一個 2×2的方陣,對角線上元素全為 0,代表著樣例被正確分類的代價是0,其他元素則分別代表著少數類樣例被錯分類到多數類的錯誤代價ca和多數類樣例被錯分到少數類的錯誤代價cb.在設置代價矩陣時,ca要大于cb.之后,通過最小化錯誤分類的總代價,可以使ELM模型對少數類的錯誤分類更加敏感,從而達到解決分類中的類別不平衡問題.用代價敏感的ELM來解決Bug報告分類中不平衡問題的過程可以用算法2來表示.
算法2.代價敏感的ELM的訓練算法.
(1) 輸入:條件屬性矩陣X,標簽屬性矩陣T//輸入的矩陣已按類別分組
(2) 初始化:隱層節點數ncc,代價矩陣D;隨機初始化:輸入權重α,隱層偏置B
(3) 用公式(8)計算隱層輸出值矩陣H
(4) 通過公式(10)求解β*
(5) 返回β*
本文之前介紹的ELM方法和代價敏感的ELM方法都是有監督學習的方法,監督學習的方法需要訓練數據既有條件屬性也要有與之相對應的標簽屬性.但是在軟件測試的過程中,條件屬性容易獲得,與之對應的標簽屬性則需要精密的人工標注才可以獲得.面對這種情況,我們在本節提出一種基于模糊度的半監督學習方法[26],并且用這種方法來解決軟件 Bug報告的分類問題.在文獻[26]里已經證明,高模糊性的樣例的分類代價要明顯大于低模糊性的樣例的分類代價,所以這里使用低模糊性的樣例來填充原數據集可以避免整體的分類代價過高,而且 Wang等人[13]提出,模糊性與不確定性存在著正相關的關系,低模糊性的樣例具有低的不確定性,也就是被正確分類的可能性較大,這也是我們選擇低模糊性樣例來填充數據集的原因.
如上所述,在軟件測試過程中會產生很多無標簽的數據,而軟件 Bug報告分類問題主要就是通過學習條件屬性到標簽數據之間的映射關系,使得分類器可以自動分類這些數據.目前,在機器學習領域都是使用數據驅動的分類方法,這就需要在訓練這些分類器時,可以提供大量的有標簽的訓練數據.本文里,這些數據的標簽只有嚴重和非嚴重兩類.但是要想獲取這些標簽,就需要大量的人工標注.人工標注的工作往往耗時而且代價昂貴,這就很自然地使人們想到用未標注的數據來解決軟件測試Bug報告的分類問題.
在利用未標注的軟件測試 Bug報告數據時,我們提出了一個方法,即通過在有限的有標注的數據集上訓練出一個弱分類器,然后用這個弱分類器對未標注的數據進行分類,得到分類結果后,我們通過模糊度來衡量這些分類結果的可信程度,選擇可信程度高的數據來補充原始的訓練數據集,而這些數據的標簽屬性則是通過弱分類器給出.
理論上,上述過程可以重復多次,每一次都從未標注的數據集里挑選出可信程度大的數據來補充訓練數據集.因為訓練數據集的樣本容量在不斷地擴充,所以訓練出來的分類器的分類性能也會逐漸提高.最終的理想結果是,未標注的樣例全部被自動地加上標簽并且被擴充到訓練集里.通過這個完備的數據集,可以訓練得到一個泛化能力很強的分類器.但是需要注意:當分類器的分類精度不是很高時,錯誤分類的情況很可能會發生,也就是未標注的樣例在這種情況下很可能被標上錯誤的標簽,這樣就會干擾分類器性能的提升.因而,要想達到之前所述的理想的情況,每次選擇多少未標注的樣本來擴充訓練集,這是一個很關鍵的問題.
在實現這個方法的過程中,最關鍵的指標是未標注數據的模糊度的測量.模糊度的計算有多種方法,Zadeh等人[27]總結出了一些計算模糊度的方法,其中包括基于Hamming距離或者歐式距離的模糊性的計算方法、針對大型多類問題的模糊性計算方法.在本文中,我們利用下面的方法來計算模糊度的大小.

其中,向量μi=(μi1,μi2,…,μi,ns),μij是第i個樣本屬于第j類的隸屬度大小.
因為考慮到了數據集里類別不平衡的因素,所以在實現本節的方法時,分類器采用的是代價敏感的ELM模型.但是注意到,在計算模糊度時,需要知道樣例屬于每一個類別的后驗概率.可是在ELM的原始設計中,網絡輸出的值Y=[yij]n×ns不能表達這個信息.基于此,我們引入了softmax,將該函數作為激活函數作用到網絡的輸出層,計算公式如下所示.

算法3詳細表達了上述的基于模糊度的半監督方法.
算法3.半監督訓練算法.
(1) 輸入:有標簽的條件屬性矩陣X,標簽屬性矩陣T;無標簽的條件屬性矩陣Z
(2) 初始化:隱層節點個數ncc,代價矩陣D;隨機初始化ELM的輸入層權重和隱層偏置
(3) 根據算法2,利用數據X和T訓練一個代價敏感的ELM:CELM
(4) 利用CELM對樣本矩陣Z進行分類
(5) 得到Z上的分類結果后,通過公式11計算每個樣本的模糊度
(6) 對模糊度進行升序排列,選擇前k個樣例zx補充數據集X,
用zx被CELM分類得到的標簽zy補充T
(7) 在補充后的數據集上重新根據算法2訓練代價敏感的分類器
(8) 返回新得到的分類器的參數矩陣β
第 2.2節介紹了一種基于模糊度的半監督方法,這個方法主要為了解決訓練數據中標注樣本少的問題.這個方法的提出是基于一個假設,即未標注的樣本和少量的有標注的樣本來自同一個數據集.但是在軟件測試Bug報告的數據集里,不僅被標注的樣本量少,而且整體的樣本總量也很少.在訓練分類器時,訓練數據集的樣本量不充足會帶來的問題是使得訓練得到的分類器容易過擬合,也就是該分類器在訓練集上表現良好,可是其泛化能力很弱.在實際工作中,泛化能力弱的分類器在處理新的待分類樣本時,往往會給出錯誤的決策.
為了解決 Bug報告中有些數據集的樣本總量過少的問題,我們在本節提出一種基于模糊度的樣例遷移方法.該方法不需要被遷移的樣例與已有樣例來自同一數據集,即為了擴充訓練集的樣本容量,可以使用該方法將別的數據集里的樣例遷移到訓練集里來擴充樣本容量.
該方法的好處就是可以解決因為樣本容量少而導致的過擬合問題,但是在選擇樣例上,該方法存在著和上一節一樣的問題:如果樣本選擇不好,則同樣會導致過擬合的問題出現.為了更加客觀地選擇樣本,我們先在已有的數據集上訓練得到一個弱分類器,然后用該分類器對被遷移數據集進行分類,得到分類結果后,可以計算每個樣例的模糊度,模糊度越大,不確定性越大,所以選擇模糊度小的樣例來補充原有的數據集,這些樣例的標簽通過弱分類器得到.然后,在擴展后的數據集上再次訓練分類器.這個過程可以一直重復,直到得到合適的訓練樣本容量.
需要注意的是,為了避免數據集里類別不平衡問題的干擾,在這個方法里,我們選擇的分類器同樣是代價敏感的 ELM 模型.在實際工作中,另一個需要解決的問題是不同數據集的樣本維度通常不一樣,這個問題限制了這個方法的應用范圍.為了解決這個問題,使得我們的方法更具一般性,我們將RBM引入到該方法中.
在第1節里已經介紹了RBM.RBM可以被視為一種樣本編碼工具,即可以通過非線性變換,將樣本從一個維度空間映射到另一個維度空間.在編碼的過程中,RBM 保證編碼前和編碼后的樣本是等價的.在本節的工作里,我們采用RBM將不同數據集里的樣本編碼成統一的維度,這樣就為分類器在不同數據集上進行遷移訓練提供了可能性.我們用S={X,T}表示原數據集;同時,用St表示被遷移數據集St={Xt}.基于這些符號化的定義,該節提出來的方法可以用算法4來詳細表述.
算法4.樣本遷移算法.
(1)輸入:數據集S,其中,條件屬性矩陣X,標簽屬性矩陣T,被遷移的數據集St={Xt}
(2)初始化:ELM的隱層節點個數ncc,代價矩陣D,RBM的隱層節點個數nh.
隨機初始化:ELM的輸入層權重和隱層偏置
(3)通過算法1,利用數據X和Xt分別訓練得到兩個RBM模型
(4)通過訓練得到的RBM對X和Xt進行編碼,得到新的數據表達形式Xp和Xtp
(5)根據算法2,利用數據Xp和T,訓練得到一個代價敏感的ELM:CELM
(6)利用CELM對數據集Xtp里的樣本進行分類
(7)得到Xtp上的分類結果后,通過公式(11)計算每個樣本的模糊度
(8)對模糊度進行升序排列,選擇前k個樣例trx補充數據集Xp,
用trx被CELM分類得到的標簽try補充T
(9)在補充后的數據集上重新根據算法2訓練代價敏感的分類器
(10) 返回新得到的分類器的參數矩陣β
本文針對軟件測試Bug報告數據集里存在的3個問題提出了3個解決方法,即針對訓練數據集類別不平衡問題,提出了代價敏感的 ELM 分類方法;針對數據集被標記的樣本較少的問題,提出了基于模糊度的半監督方法;針對訓練數據集總體樣本量較少的問題,提出了基于模糊度和 RBM 的樣本遷移方法.為了驗證我們提出的方法的有效性,我們開展了3組驗證性的實驗.
在本節中,實驗所采用的數據集是真實的軟件測試Bug數據集.數據集來自3個開源項目.本節實驗里用到的數據集一共21個,其中,7個Eclipse[28]、7個Moizlla[29]、7個GNOME[30].數據集的名稱以及數據集的不平衡度都在表1~表3中被列出.其中,不平衡度Imbalance Ratio(IR)的計算如下所示.

其中,num_min是少數類的樣本個數,num_maj是多數類的樣本個數.

Table 1 Datasets of Eclipse Bug reports表1 Eclipse Bug報告數據集

Table 2 Datasets of GNOME Bug reports表2 GNOME Bug報告數據集

Table 3 Datasets of Moizlla Bug reports表3 Moizlla Bug報告數據集
在接下來的實驗里,我們采用的評價指標分別是準確率和加權的F-measure[31].其中,準確率是樣本被正確分類的比率;加權的F-measure是兩類樣例在查全率和查準率上的一個綜合性的指標,在本文實驗里,該指標更能反映出分類器對嚴重Bug的誤報程度.準確率的計算如下所示:

其中,Accuracy是準確率,TP、FP、TN和FN的關系可以用表4表示.

Table 4 Confusion matrix表4 混淆矩陣
F-measure的計算如下:

其中,在本文實驗里,γ等于1,Precision代表查準率,Recall代表查全率,這兩個指標的計算可由下面的公式表達.

本文所用到的加權F-measure計算如下:

其中,wF是加權的F-measure;W=(w1,w2),w1是第1類樣例占的比例,w2是第2類樣例占的比例.
本節的第 1個實驗是驗證代價敏感的 ELM在不平衡數據集上的分類效果.作為對比,我們用傳統的 ELM在相同的數據集上進行實驗.除此之外,我們還比較了基本的分類器,即樸素貝葉斯模型(NB)、BP神經網絡模型(BPNN)和支持向量機(SVM)[32].數據集的劃分是:把數據集平均分成5份,每次隨機取3份作為訓練集,剩下的2份作為測試集.為了保證客觀性,我們對兩個方法都進行了100次實驗,最后的結果是取這100次實驗的平均值.在每次實驗里,為了保證公平性,代價敏感的ELM和傳統的ELM的隱層節點數以及BPNN的隱層節點數都被設置成一樣的個數,并且兩個模型的輸入層權重和隱層偏置也都被相同的隨機數賦值.我們在實驗里給權重和偏置隨機賦權的方法是在區間[0,1]里隨機取值.表5~表10給出了這組實驗的對比結果.

Table 5 Testing accuracies on Eclipse datasets表5 Eclipse數據集上的測試準確率

Table 6 WeightedF-measures on Eclipse datasets表6 Eclipse數據集上的加權F-measures

Table 7 Testing accuracies on GNOME datasets表7 GNOME數據集上的測試準確率

Table 8 WeightedF-measures on GNOME datasets表8 GNOME數據集上的加權F-measures

Table 9 Testing accuracies on Moizlla datasets表9 Moizlla數據集上的測試準確率

Table 10 WeightedF-measures on Moizlla datasets表10 Moizlla數據集上的加權F-measures
通過表1~表3的最后一列可以看出,Bug報告數據集都是有著不平衡度的數據集,而且有些數據集的不平衡度較大.在處理數據類別不平衡這個問題時,通過給少數類樣例更大的錯誤分類代價,得到的分類準確率在絕大多數 Bug報告數據集上有了很明顯的提升.雖然在表7中,GNOME_Evolution_Mailer的準確率結果要偏低,但是通過加權的F-measure值的比較可以看出,代價敏感的分類器在重要數據樣本的分類上面表現仍舊良好,也就是對嚴重Bug的誤報率較低.而且通過在所有數據集上比較加權的F-measure值可以看到,基于代價的分類模型都能取得很好的效果.與其他傳統的分類器相比,ELM 方法需要設定的參數更少,尤其與 BPNN的比較中,ELM的訓練時間要遠遠低于BP迭代調參所需要的時間,并且在絕大多數數據集上,ELM方法可以取得較好的效果.在圖3中,我們比較了欠采樣方法(RUS-ELM)、過采樣方法(ROS-ELM)、合成過采樣方法(SMOTE)與代價敏感方法.欠采樣方法是對多數類樣例進行隨機刪減,可以看出,因為減少了訓練樣本的容量,并且在刪減樣本的過程中容易丟失重要數據,所以該方法效果不是很好;過采樣的方法則是對少數類樣例進行擴充,該方法可能會受到冗余數據的影響,造成分類器過擬合,對分類器泛化能力造成不好的影響;SMOTE方法相對表現較好,但是該方法容易造成類間的 overlapping現象,且在類別臨界面生成樣例時,容易將合成的多數類樣例標記成少數類類別,從而不利于分類器對數據分布特點的學習.通過比較,基于代價敏感的平衡方法在絕大部分數據集上都有較好的結果,而且基于代價的方法表現得更加穩定,更適合被用于實際的工作中.從效率上來看,基于代價的方法不需要事先對數據集進行平衡化的預處理,而是可以進行端到端的訓練,從而更加滿足本文研究領域的需求.

Fig.3 Comparison among RUS,ROS,SMOTE and cost-based method圖3 欠采樣、過采樣、合成過采樣和代價敏感方法的比較

Fig.3 Comparison among RUS,ROS,SMOTE and cost based method (Continued 1)圖3 欠采樣、過采樣、合成過采樣和代價敏感方法的比較(續1)

Fig.3 Comparison among RUS,ROS,SMOTE and cost based method (Continued 2)圖3 欠采樣、過采樣、合成過采樣和代價敏感方法的比較(續2)
圖3中的結果都是實驗重復100次得到的平均值,藍色圖是準確度的結果,綠色圖是加權F-measure值的結果.1~5分別代表ELM、CELM、RUS-ELM、ROS-ELM和SMOTE-ELM.
本節的第 2個實驗是驗證基于模糊度的半監督方法在擴充訓練集樣本容量上的有效性.在這個實驗里,我們采用的分類器是代價敏感的 ELM 模型,目的是為了避免數據集里不平衡問題的干擾.在該實驗里,對原始數據集的劃分是:將數據集劃分成6份,每次隨機選擇其中的3份作為訓練集,在剩下的數據中,隨機選擇2份作為測試集,最后留下的數據作為驗證集.其中,驗證集則是本文第2.2節里提到的未標注數據集.在實驗過程中,我們先在原始的訓練集上訓練得到一個弱分類器,然后在驗證集上對樣例進行分類,之后通過模糊度的大小選擇一定數量的驗證集樣例來擴充原始的訓練集,然后用擴充得到的數據集再次訓練一個分類器.為了保證客觀性,前后兩個分類器的各項參數的設置完全一樣,具體操作方法如第 1個實驗所述.為了通過對比顯示我們方法的有效性,我們用兩次訓練得到的分類器對測試集的樣本進行分類,最后通過上述兩個指標來評價分類結果,該結果同樣是對100次的實驗結果求平均值得到的最終結果.我們用First表示在原始數據集上訓練得到的分類器的測試結果,用Second表示用擴充后的數據集訓練的分類器的測試結果.這部分的實驗見表11.

Table 11 Experimental results of semi-supervised approach表11 半監督方法的實驗結果
從表11可以看出,通過基于模糊度的半監督方法來擴充數據集,并且用新的數據集再次訓練分類器,所得到的分類器的分類效果在每個數據集上都有了提升.這證明了我們提出來的這個方法對于改善分類器的泛化能力是有效的.
本節的第3個實驗是驗證基于模糊度和RBM的樣本遷移方法的有效性.在這個實驗里,我們采用的分類器同樣是代價敏感的ELM模型.我們對原始數據集的劃分方法和第1個實驗里數據集劃分方法一樣.對于被遷移的數據集,我們沒有采用任何的劃分方法.在進行分類之前,我們首先對原始數據集的整體進行 RBM 編碼,同時對被遷移的數據集的整體進行RBM編碼.在這兩次編碼中,我們采用3個級聯的RBM對輸入數據進行維度空間的變換.在編碼過程中,我們只需要保證兩次編碼的輸出維度一樣即可,中間隱層的維度則可以自主調節.分類實驗的具體操作過程是,先在原始的訓練集上訓練得到一個分類器,然后對被遷移的樣本進行分類,用分類結果計算每個樣本的模糊度大小,根據模糊度大小來選擇樣本來擴充原始的訓練集.之后,再利用擴充后的訓練集重新訓練一個分類器.在實驗過程中,前后兩個分類器的參數設置完全一樣.為了體現實驗的客觀性,我們重復本實驗的全部過程(編碼過程和分類過程)100次,最后取這100次的平均值作為實驗結果.我們用Before表示在原始數據集上訓練得到的分類器的測試結果,用After表示在被擴充后的數據集上訓練得到的分類器的測試結果.這些結果展示在表12中.

Table 12 Experimental results of transferring approach表12 遷移方法的實驗結果
從表12中我們可以看出,無論是準確率還是加權的F-measure值,再次訓練的分類器都取得了較好的效果.這個結果顯示,基于RBM和模糊度的樣本遷移方法在擴充樣本容量并且提升分類器的泛化能力這些方面是有效的.
本節的實驗基本驗證了我們提出方法的可行性和有效性.其中,如第 3節所述,在利用半監督方法擴充訓練集時,理論上可以進行多次迭代,逐漸擴充訓練集的樣本容量.在之前的實驗里,我們設置的迭代次數為兩次,即對分類器進行再訓練的優化策略.再訓練的結果已經表明,我們的方法是有效的.為了進一步驗證我們的方法在數據集樣本量繼續擴充的條件下仍舊是有效的,我們將迭代次數增加,圖4顯示了隨著迭代次數增加,我們的方法在每個數據集上的表現.
在上面的實驗中,為了保證客觀性,我們將實驗重復了 100次,然后取平均值.在每一次的實驗中,我們提前將數據集按照3:2:1的比例分別分成訓練集、測試集和驗證集.其中,驗證集是用來擴充訓練集樣本容量的數據集合.然后,我們利用半監督方法逐步地對訓練數據集擴充了5次,每一次擴充后都在測試集上進行測試,并給出上圖所示的測試結果.值得注意的是,為了克服隨機賦權的影響,5次迭代中,分類器的隨機參數都是相同的值,實驗結果就只會受到數據集樣本容量變化的影響.從圖4可以看出,在利用本文的半監督方法的前提下,隨著數據集樣本容量的增加,分類器的性能也在逐步提升,這一現象在 21個數據集上都有體現.通過這組實驗,驗證了我們提出來的方法的有效性,即在人工標記的數據不充足的條件下,可以利用有效的半監督機制[33,34]來逐步擴充訓練樣本集,最終可以達到提升分類性能的目的.

Fig.4 Results of five tests on 21 datasets圖4 21個數據集5次測試的結果
本節實驗里,網絡結構參數、代價矩陣的設置以及其他參數的具體情況,都詳細地列在了本文的附錄里.
本文主要解決軟件測試Bug報告中的樣例分類問題.在實際工作中,我們發現Bug報告數據集普遍存在著3個問題:第1個是樣本類別不平衡問題,第2個是數據集里被標注的樣本個數不充足的問題,第3個是數據集的樣本總容量不充足的問題.這3個問題都會對分類工作產生不良的影響.為了解決這3個問題,我們提出了3種方法:第1種是基于代價敏感的ELM模型來增加少數類樣例被錯誤分類的代價,從而解決類別不平衡問題帶來的影響;第2種是基于模糊度的半監督方法來自動標注沒有標簽的數據,從而擴充有標簽的數據集;第3種是基于RBM和模糊度的樣本遷移方法來擴增原有數據集的方法.本文通過幾個實驗驗證了我們提出的方法是有效的、可行的.最后,可以注意到,本文提出來的方法具有很好的擴展性,可以與不同的模型[35-38]相結合.本文未來的研究工作將與集成學習[39,40]的方法相結合,以進一步提升目前的方法在 Bug報告分類問題上的效果,同時將結合后的方法應用于更多的相關領域[41-43].
附錄
證明:用softmax的輸出來表示后驗概率的合理性.
定義x(1),…,x(m)為m個輸入向量,且x(i)∈?1×ncc,ncc為輸入向量的維度,x(i)j是向量x(i)第j維屬性值,i=1,2,…,m,j=1,2,…,ncc.對ELM的輸出層來講,其輸入向量x(i)是隱層的輸出向量,因此在ELM中,ncc為隱層節點數.為了簡化表達,下文出現的x表示x(i),?i=1,2,…,m,y(1),…,y(m)為輸入向量對應的真實類別標簽,其中,y(i)∈{1,2,…,ns},i=1,2,…,m.ns為類別個數,在ELM中,ns表示輸出節點數.

定義一個概率函數π():?1×ncc→[0,1]ns,該函數將輸入向量x映射為一個ns維向量,其中,第u維π(x)u代表輸入向量屬于第u類的概率大小.基于以上定義,下面證明π()具有softmax函數形式.
根據π()的定義,可知π()應滿足以下性質:


根據信息論,π()的熵可以定義為

根據信息論最大熵原理,即通常選取熵值最大的概率分布作為隨機變量的分布,所以在公式(A.2)~公式(A.4)的約束下,最大化公式(A.5),該過程是一個求條件極值的問題,通常使用拉格朗日乘數法求解該問題.這里,拉格朗日方程可以寫成:

其中,βj,v與λi為拉格朗日乘數,且βj,v為矩陣β∈?ncc×ns中的元素.注意到條件(A.2)為不等式,所以無法被包含進方程(A.6),但是可以在方程(A.6)的解中,選擇滿足條件(A.2)的值為最終解.在求解過程中,L對π(x(i))v求偏導,且極值在偏導數等于0處取得,即

其中,βv∈?ncc×1為β中第v列列向量.對公式(A.7)等價變形有:

根據公式(A.3),有:

即


公式(A.11)右側分式上下同乘e,有:

公式(A.12)可以簡化成:

在 ELM 中,βv可被看作是連接隱層與輸出層第v個節點的權重向量,β是輸出層權重,則x(i)βv是網絡輸出yiv;同理,x(i)βu=yiu.綜上,證明滿足概率性質的概率函數π()具有softmax的函數形式,從而證明用softmax函數作用在ELM的輸出層輸出后驗概率的合理性. □
實驗1的參數設置.

數據集 代價矩陣 隱層節點數Eclipse_CDT_cdt-core [0,5;2,0] 500 Eclipse_JDT_Core [0,3;1,0] 1 000 Eclipse_JDT_Debug [0,3,1,0] 500 Eclipse_PDE_UI [0,3;1,0] 500 Eclipse_Platform_Debug [0,5;2,0] 200 Eclipse_Platform_SWT [0,5;2,0] 1 500 Eclipse_Platform_UI [0,3;1,0] 2 000 GNOME_ekiga_general [0,5,2,0] 500 GNOME_Evolution_Calendar [0,5;2,0] 1 000 GNOME_Evolution_Contacts [0,5;2,0] 1 000 GNOME_Evolution_Mailer [0,2;1,0] 3 000 GNOME_Evolution_Shell [0,3;1,0] 500 GNOME_gnome-panel_Panel [0,5;2,0] 500 GNOME_gnome-terminal_general [0,5;2,0] 1 500 Moizlla_Core_Printing [0,5;1,0] 500 Moizlla_Core_XPCOM [0,5;2,0] 500 Moizlla_Core_XPConnect [0,2;1,0] 100 Moizlla_Core_XUL [0,5;2,0] 1 000 Moizlla_Thunderbird_General [0,5;2,0] 1 000 Mozilla_Core_Layout [0,5;2,0] 1 500 Mozilla_Core_Security_UI [0,5;2,0] 400
實驗2的參數設置.

數據集 代價矩陣 隱層節點數 k值Eclipse_CDT_cdt-core [0,5;2,0] 200 50 Eclipse_JDT_Core [0,6;1,0] 200 50 Eclipse_JDT_Debug [0,3;1,0] 200 10 Eclipse_PDE_UI [0,3;1,0] 100 10 Eclipse_Platform_Debug [0,5;2,0] 200 10 Eclipse_Platform_SWT [0,3;2,0] 1 000 50 Eclipse_Platform_UI [0,5;2,0] 500 5 GNOME_ekiga_general [0,5;2,0] 500 50 GNOME_Evolution_Calendar [0,3;1,0] 1 000 50 GNOME_Evolution_Contacts [0,3;1,0] 500 20 GNOME_Evolution_Mailer [0,5;2,0] 2 500 200 GNOME_Evolution_Shell [0,3;1,0] 200 50 GNOME_gnome-panel_Panel [0,3;1,0] 500 50 GNOME_gnome-terminal_general [0,3;1,0] 500 50 Moizlla_Core_Printing [0,3;1,0] 500 50 Moizlla_Core_XPCOM [0,3;1,0] 200 10 Moizlla_Core_XPConnect [0,2;1,0] 100 5 Moizlla_Core_XUL [0,5;2,0] 200 50 Moizlla_Thunderbird_General [0,5;2,0] 500 50 Mozilla_Core_Layout [0,5;2,0] 1 500 50 Mozilla_Core_Security_UI [0,5;2,0] 200 50
實驗3的參數設置.

數據集 被遷移數據集 代價矩陣 隱層節點數 k值Eclipse_CDT_cdt-core Eclipse_JDT_Core [0,5;2,0] 20 10 Eclipse_JDT_Core Eclipse_JDT_Debug [0,5;2,0] 20 10 Eclipse_JDT_Debug Eclipse_Platform_Debug [0,5;2,0] 200 10 Eclipse_PDE_UI Eclipse_Platform_Debug [0,5;2,0] 50 10 Eclipse_Platform_Debug Eclipse_Platform_SWT [0,5;2,0] 200 10 Eclipse_Platform_SWT Eclipse_CDT_cdt-core [0,5;2,0] 100 10 Eclipse_Platform_UI Eclipse_PDE_UI [0,5;2,0] 20 10 GNOME_ekiga_general GNOME_Evolution_Calendar [0,5;2,0] 100 50 GNOME_Evolution_Calendar GNOME_Evolution_Shell [0,5;2,0] 200 20 GNOME_Evolution_Contacts GNOME_Evolution_Shell [0,5;2,0] 200 10 GNOME_Evolution_Mailer GNOME_gnome-terminal_general [0,3;1,0] 20 10 GNOME_Evolution_Shell Moizlla_Core_Printing [0,5;2,0] 200 10 GNOME_gnome-panel_Panel GNOME_ekiga_general [0,3;1,0] 50 10 GNOME_gnome-terminal_general GNOME_gnome-panel_Panel [0,5;2,0] 100 50 Moizlla_Core_Printing Moizlla_Core_XPCOM [0,5;2,0] 20 10 Moizlla_Core_XPCOM Moizlla_Core_Printing [0,5;2,0] 20 10 Moizlla_Core_XPConnect Moizlla_Core_XUL [0,5;2,0] 20 10 Moizlla_Core_XUL Moizlla_Core_XPConnect [0,5;2,0] 20 10 Moizlla_Thunderbird_General Moizlla_Core_XUL [0,5;2,0] 30 10 Mozilla_Core_Layout Moizlla_Core_XPCOM [0,5;2,0] 20 10 Mozilla_Core_Security_UI Moizlla_Core_XPCOM [0,5;2,0] 20 10

序號 RBM節點數(原數據集)RBM節點數(被遷移數據集)1 100-500-100 100-200-100 2 100-200-100 100-200-100 3 100-500-100 100-500-100 4 100-500-200 100-1000-200 5 100-500-100 100-500-100 6 500-500-500 500-500-500 7 100-500-200 100-200-200 8 100-500-200 100-200-200 9 500-500-100 500-500-100 10 500-500-100 500-500-100 11 300-300-200 300-300-200 12 100-200-100 100-200-100 13 100-200-100 500-500-100 14 100-200-100 100-200-100 15 100-500-200 100-200-200 16 100-500-200 100-200-200 17 100-500-200 100-200-200 18 100-500-200 100-200-200 19 100-500-200 100-200-200 20 100-500-200 100-200-200 21 100-500-200 100-200-200
實驗4的參數設置.

數據集 代價矩陣 隱層節點數 k值Eclipse_CDT_cdt-core [0,5;2,0] 200 10 Eclipse_JDT_Core [0,6;1,0] 200 10 Eclipse_JDT_Debug [0,3;1,0] 200 20 Eclipse_PDE_UI [0,3;1,0] 100 10 Eclipse_Platform_Debug [0,5;2,0] 200 10 Eclipse_Platform_SWT [0,3;2,0] 1 000 50 Eclipse_Platform_UI [0,5;2,0] 300 20 GNOME_ekiga_general [0,5;2,0] 500 20 GNOME_Evolution_Calendar [0,3;1,0] 1 000 20 GNOME_Evolution_Contacts [0,3;1,0] 500 20 GNOME_Evolution_Mailer [0,5;2,0] 2 500 100 GNOME_Evolution_Shell [0,5;2,0] 200 10 GNOME_gnome-panel_Panel [0,3;1,0] 500 50 GNOME_gnome-terminal_general [0,5;2,0] 500 10 Moizlla_Core_Printing [0,3;1,0] 500 10 Moizlla_Core_XPCOM [0,2;1,0] 200 5 Moizlla_Core_XPConnect [0,2;1,0] 200 5 Moizlla_Core_XUL [0,5;2,0] 200 20 Moizlla_Thunderbird_General [0,5;2,0] 500 20 Mozilla_Core_Layout [0,5;2,0] 1 500 50 Mozilla_Core_Security_UI [0,5;2,0] 200 20