沈 琦 ,錢 瑩 ,鄒艷珍 ,伍仕駿 ,謝 冰
1(高可信軟件技術(shù)教育部重點(diǎn)實(shí)驗(yàn)室(北京大學(xué)),北京 100871)
2(北京大學(xué) 信息科學(xué)技術(shù)學(xué)院,北京 100871)
當(dāng)前軟件開發(fā)過程中通常需要大量復(fù)用已有的代碼庫或開源軟件[1-3].在復(fù)用過程中,用戶的開發(fā)任務(wù)需求習(xí)慣使用自然語言描述,并且通常一個(gè)開發(fā)任務(wù)的代碼實(shí)現(xiàn)涉及到多個(gè)APIs 調(diào)用.因此,了解待復(fù)用軟件項(xiàng)目/代碼庫可提供的功能特征十分重要[4-6].一方面,這些功能特征可以輔助用戶快速將開發(fā)任務(wù)映射到需要調(diào)用的APIs;另一方面,功能特征介紹可以幫助用戶進(jìn)一步明確自己的任務(wù)需求,防止需求描述不準(zhǔn)確造成的時(shí)間浪費(fèi).
一般來說,了解軟件的功能特征可以通過閱讀該軟件提供的功能描述文檔.然而,不同于傳統(tǒng)商業(yè)軟件,開源軟件通常缺少高質(zhì)量的功能描述文檔,在使用過程中常常存在下述問題[7-9]:(1) 文檔介紹的功能較少,且描述不準(zhǔn)確.由于人工編寫軟件功能描述文檔需要大量的時(shí)間,很多時(shí)候,開發(fā)者在文檔中只對(duì)一些典型的、基礎(chǔ)的軟件功能進(jìn)行了介紹,且文檔中的功能描述方式可能與復(fù)用者的功能需求存在一定差別.譬如在一些軟件功能文檔中,索引描述的可能是高層次的軟件功能類別而非具體的功能特性;某些功能文檔中僅僅是按照API 的名稱進(jìn)行排序、組織,這使得在官方文檔中自動(dòng)定位到復(fù)用者需要的信息并不是一件簡單的事情;(2) 文檔與軟件版本不一致.持續(xù)更新軟件文檔是一件很困難的事情.尤其是當(dāng)前軟件的迭代周期很短,軟件功能不斷變化,讓軟件文檔始終與最新的軟件功能特性、API 使用場(chǎng)景等保持一致是一件需要耗費(fèi)大量時(shí)間和精力的事情.因此,當(dāng)開發(fā)人員想要使用一些新的軟件功能特性或者將API 應(yīng)用到一些新的場(chǎng)景中時(shí),很可能無法在官方文檔中找到對(duì)應(yīng)的說明信息.
為此,需要研究提出一種軟件功能特征的自動(dòng)挖掘方法.該方法能夠利用開源軟件的各類相關(guān)資源,自動(dòng)地挖掘出軟件項(xiàng)目/代碼庫的功能特征,并對(duì)其進(jìn)行有效組織、整理以方便復(fù)用者進(jìn)行檢索和瀏覽.在現(xiàn)有工作中,研究者們已經(jīng)通過分析處理各類軟件資源(包括官方文檔、郵件列表、缺陷報(bào)告、問答網(wǎng)站等等),提出了多種軟件功能特征/描述挖掘方法[10-12].但是,這些方法的主體采用自然語言處理技術(shù),很大程度上依賴軟件文檔中大量重復(fù)出現(xiàn)的軟件功能描述語句,或借助人工制定的單詞白名單[13]、文檔標(biāo)題等結(jié)構(gòu)信息[14]來提取軟件功能描述.由于不同軟件項(xiàng)目間的領(lǐng)域詞匯和文檔結(jié)構(gòu)通常存在差異,因此方法難以在跨項(xiàng)目場(chǎng)景下保證高準(zhǔn)確率.此外,一些代碼注釋或代碼摘要生成[15,16]的工作采用模板填充或機(jī)器學(xué)習(xí)的思路,結(jié)合代碼中API 的上下文自動(dòng)生成代碼的自然語言注釋或摘要.此類工作雖然同樣能以自然語言功能描述的形式幫助開發(fā)者理解示例代碼,進(jìn)而學(xué)習(xí)軟件項(xiàng)目,但相較于抽取式的功能描述挖掘方法,其生成描述文本的可讀性較差.而對(duì)于一個(gè)新發(fā)布的軟件項(xiàng)目來說,收集整理大量用于學(xué)習(xí)的使用示例也是一件非常耗時(shí)、耗力的事.
針對(duì)上述問題,本文提出了一種融合代碼與文檔的軟件功能特征挖掘方法.該方法以動(dòng)賓短語形式描述一項(xiàng)軟件功能特征,通過迭代挖掘軟件的源代碼和Stack Overflow 開發(fā)交流記錄,實(shí)現(xiàn)更為準(zhǔn)確的軟件功能特征提取,并構(gòu)建了多維的、層次化的軟件功能特征視圖.對(duì)比現(xiàn)有工作,本文的主要貢獻(xiàn)包括:
(1) 提出了一種軟件概念的迭代抽取方法,將源代碼中的類名作為種子概念,通過迭代挖掘得到新的軟件概念集,有效地指導(dǎo)了軟件文檔中軟件功能特征動(dòng)賓短語的挖掘;
(2) 提出了一種融合源代碼與Stack Overflow 交流記錄的軟件功能特征挖掘方法,以軟件概念為核心,提高了軟件功能特征挖掘的準(zhǔn)確率、覆蓋率和效率;
(3) 在大量軟件項(xiàng)目數(shù)據(jù)上對(duì)本文方法進(jìn)行了實(shí)驗(yàn)并開源了實(shí)驗(yàn)結(jié)果.實(shí)驗(yàn)結(jié)果表明,本文方法獲取的軟件功能特征可以覆蓋Apache POI 項(xiàng)目官方文檔中列舉的95.65%的軟件常用功能,從軟件項(xiàng)目Stack Overflow交流記錄中進(jìn)行軟件功能特征挖掘的準(zhǔn)確率達(dá)到了93.78%.
本文第1 節(jié)介紹我們的方法框架以及基本概念.第2 節(jié)具體介紹所提出的功能特征挖掘方法.第3 節(jié)通過具體開源軟件數(shù)據(jù)對(duì)本文方法進(jìn)行實(shí)驗(yàn)評(píng)估.第4 節(jié)介紹相關(guān)工作并進(jìn)行討論.第5 節(jié)總結(jié)全文.
軟件功能是軟件系統(tǒng)或部件定義的目標(biāo)或特征動(dòng)作[10].傳統(tǒng)上,軟件文檔中會(huì)用一段話來描述軟件功能(包括功能的目標(biāo)或動(dòng)作,前提和后驗(yàn)條件、執(zhí)行序列和輸入輸出等)[11,13].本文為了幫助用戶進(jìn)行快速瀏覽和定位,采用動(dòng)賓短語的形式描述軟件的功能特征(functional feature)[17].軟件功能特征的操作、對(duì)象、約束條件等組成分別對(duì)應(yīng)于動(dòng)賓短語中的動(dòng)詞、作為賓語的名詞短語和介詞短語等.譬如開源軟件項(xiàng)目Apache POI 具有“set up print area”“convert a huge.csv file to excel”等功能特征.這種動(dòng)賓短語描述的功能特征形式簡潔、明確,易于開發(fā)人員理解,直接對(duì)應(yīng)到復(fù)用該軟件可以實(shí)現(xiàn)的編程目標(biāo)或特征動(dòng)作.
軟件功能特征本質(zhì)上是一段軟件功能描述文本的代稱.但軟件功能的概念源自需求領(lǐng)域,因此功能特征的粒度一直是研究者們關(guān)注的重點(diǎn).在本文工作中,將軟件功能特征分為兩個(gè)層次.
(1) 基本功能特征:使用一個(gè)軟件API 即可完成的功能特征.對(duì)復(fù)用者來說,軟件功能的基本單位是API,則一個(gè)API 對(duì)應(yīng)的軟件功能稱為基本軟件功能特征;
(2) 復(fù)合功能特征:需要組合調(diào)用多個(gè)APIs 才能完成的功能特征.通常來說,一個(gè)開發(fā)任務(wù)對(duì)應(yīng)的軟件功能需要多個(gè)APIs 聯(lián)合實(shí)現(xiàn).譬如,實(shí)現(xiàn)“iterate over cells”功能需要使用循環(huán)調(diào)用Sheet 對(duì)象的getRow 和Row 對(duì)象的getCell 方法協(xié)作完成.
基于這種區(qū)分,本文在軟件功能特征挖掘過程中對(duì)軟件的源代碼和Stack Overflow 問答文檔進(jìn)行了綜合分析,首先從源代碼中提取基本功能特征和軟件核心概念,并以此為基礎(chǔ)指導(dǎo)從軟件文檔中精確提取復(fù)合軟件功能特征.具體的方法流程如圖1 所示.
Fig.1 The framework of our approach圖1 本文的方法框架
具體的方法流程主要包括:
基本軟件功能特征挖掘.以軟件項(xiàng)目源代碼作為數(shù)據(jù)源,解析、提取其中的類、方法、字段等信息,形成代碼元素集合.然后,依據(jù)訪問控制修飾符篩選代碼元素集合中的API,形成公共調(diào)用接口集合,并將每個(gè)API 名稱解析、修正、還原為動(dòng)賓短語,從而得到軟件的基本軟件功能特征集.
軟件概念挖掘.軟件代碼中包含軟件功能特征最核心的基礎(chǔ)概念.為此,本文采用迭代擴(kuò)充的思路,最初以代碼元素(主要是類名)作為種子概念,然后設(shè)計(jì)啟發(fā)式規(guī)則提取新的概念補(bǔ)充到概念集合中,形成候選概念集合;對(duì)當(dāng)前的候選概念集合進(jìn)一步加以過濾,保障概念擴(kuò)充的準(zhǔn)確性.重復(fù)上述過程,直到某次擴(kuò)充時(shí)沒有新增概念為止,即得到軟件項(xiàng)目的核心概念集合.
復(fù)合軟件功能特征挖掘.以Stack Overflow 的軟件問答文檔作為數(shù)據(jù)源,首先對(duì)文檔中的自然語言文本片段進(jìn)行句法分析,得到動(dòng)賓短語集合.然后,利用上文得到的軟件核心概念集合,篩選出與相關(guān)的動(dòng)賓短語作為候選復(fù)合軟件功能特征名稱.最后,合并相似的軟件功能特征名稱,從而得到復(fù)合軟件功能特征名稱集.
軟件功能特征視圖構(gòu)建.挖掘基本功能特征和復(fù)合功能特征之間的關(guān)聯(lián)關(guān)系.將功能特征名稱中賓語對(duì)象之間的關(guān)聯(lián)關(guān)系與源代碼中類之間的繼承關(guān)系相對(duì)應(yīng),將來源于同一個(gè)討論帖的功能特征之間建立關(guān)聯(lián),構(gòu)建多維的、層次化的功能特征視圖.
為了進(jìn)一步闡明上述框架,我們通過一個(gè)具體實(shí)例來展示本文功能特征抽取的基本過程.圖2 展示了一個(gè)Stack Overflow 討論帖中對(duì)POI 軟件一次使用的情況.這個(gè)帖子中的動(dòng)賓短語“apply background color for the rows in excel sheet(由紅色下劃線標(biāo)注)”是POI 軟件項(xiàng)目的一項(xiàng)功能特征,其作用是為excel 文件中的行設(shè)置背景顏色.但同時(shí)帖子中包含大量的其他動(dòng)賓短語,那些藍(lán)色下劃線標(biāo)注的動(dòng)賓短語與功能特征無關(guān),綠色下劃線標(biāo)注的動(dòng)賓短語則與紅色下劃線標(biāo)注的短語含義相似.因此,如何準(zhǔn)確地挖掘出紅色下劃線標(biāo)注的功能特征短語是本文面臨的主要技術(shù)挑戰(zhàn).基于上述框架,本文首先從POI 的源代碼中提取代碼元素集合,獲得“color”這個(gè)基本概念.然后,使用軟件概念集合與基于軟件開發(fā)和問答論壇場(chǎng)景建立的停用詞表篩選動(dòng)賓短語.由于動(dòng)詞“apply”不屬于停用詞表,因此,“apply background color for the rows in excel sheet”成為候選功能特征.同理,通過過濾掉藍(lán)色下劃線標(biāo)注的動(dòng)賓短語,留下紅色下劃線和綠色下劃線標(biāo)注的動(dòng)賓短語作為候選功能特征.最后,合并相似的候選功能特征,由于紅色下劃線和綠色下劃線標(biāo)注的動(dòng)賓短語相似度很高,為避免冗余,合并為一個(gè)軟件功能特征.因此,從這個(gè)討論帖中提取出的軟件功能特征為“apply background color for the rows in excel sheet”.
Fig.2 A software functional feature on Stack Overflow Q&A post圖2 Stack Overflow 軟件問答文檔中的功能特征舉例
基于上述框架,這里對(duì)本文提出的融合代碼與文檔的軟件功能特征挖掘方法進(jìn)行詳細(xì)介紹.
基本軟件功能特征是指由單個(gè)API 即可實(shí)現(xiàn)的軟件功能.本文利用軟件項(xiàng)目源代碼中的信息來挖掘基本軟件功能特征名稱,挖掘過程主要分為代碼元素的提取、公共調(diào)用接口的提取和API 名稱的解析這3 個(gè)步驟.
1) 代碼元素的提取
本文中代碼元素特指軟件源代碼中的類名、方法名和字段名.為了得到軟件的代碼元素信息,本文首先使用javalang 來解析軟件項(xiàng)目源代碼,獲得代碼元素集合.對(duì)于一個(gè)軟件項(xiàng)目的源代碼,javalang 深度優(yōu)先遍歷軟件目錄,將源代碼文件解析成抽象語法樹(abstract syntax tree,簡稱AST),然后提取AST 中的類和方法元素,形成代碼元素集合.針對(duì)每個(gè)Java 類,獲得類名稱、類中有字段和方法,類可能與其他類有關(guān)系(比如繼承自某個(gè)類或者實(shí)現(xiàn)了某個(gè)接口);針對(duì)每個(gè)Java 方法,獲得方法名稱、參數(shù)和返回值以及說明該方法訪問權(quán)限的修飾符等.這些抽取出的代碼元素信息接下來不僅僅是基本軟件功能特征名稱的來源,還會(huì)作為種子概念成為軟件概念挖掘的數(shù)據(jù)源.
2) 公共調(diào)用接口的提取
雖然基本軟件功能特征名稱與API 的粒度一致,但是并非所有API 都是基本軟件功能特征.有些API 僅能夠在該軟件項(xiàng)目的同一包或同一類中被調(diào)用,因此不能為軟件項(xiàng)目的復(fù)用者所用.本文提取出軟件項(xiàng)目的公共調(diào)用接口,作為對(duì)應(yīng)于基本軟件功能特征的API.
在Java 軟件項(xiàng)目中,可以使用訪問控制修飾符來說明訪問權(quán)限,以保護(hù)對(duì)類、變量、方法和構(gòu)造方法的訪問.軟件功能是軟件用戶有權(quán)限調(diào)用的API,這些API 至少需要是對(duì)軟件項(xiàng)目中所有類可見的.因此,本文提取出以“public”關(guān)鍵字修飾的方法作為公共調(diào)用接口,也就是基本軟件功能特征名稱所對(duì)應(yīng)的API.
3) API 名稱的解析
本文中軟件功能特征名稱是以動(dòng)賓短語的形式存在的.我們根據(jù)源代碼中的API 命名特點(diǎn),將API 名稱解析為動(dòng)賓短語,從而得到基本軟件功能特征名稱.
在軟件項(xiàng)目源代碼中,API 命名有以下兩個(gè)主要特點(diǎn):(1) 在表現(xiàn)形式上,軟件項(xiàng)目中的API 名稱基本上都遵循駝峰式命名法.(2) 在API 名稱的自然語言含義方面,軟件項(xiàng)目中的方法命名一般是動(dòng)詞或動(dòng)詞短語,與方法所施加的對(duì)象共同組成動(dòng)賓短語,即動(dòng)詞+名詞的形式.一般可以通過方法名稱直接獲知該方法實(shí)現(xiàn)什么樣的功能.為此,本文將API 名稱按照駝峰式命名法進(jìn)行切分,即可得到候選動(dòng)賓短語.在此基礎(chǔ)上,進(jìn)一步修正、還原動(dòng)賓短語,得到基本功能特征名稱.其中,修正的過程是指:將動(dòng)賓短語中的單詞首字母還原為小寫字母.如上文所述,駝峰式命名法利用單詞的首字母大寫來表示單詞的起始,因此,需要將單詞中的字母全部還原為小寫字母.例如,開源軟件項(xiàng)目Apache POI 的“setBorderColor”方法切分后成為“set Border Color”短語,還需要將短語中的詞語還原為原形,變成“set border color”.還原的過程是指:將動(dòng)賓短語中的單詞還原為原形.動(dòng)賓短語中有些單詞使用的是復(fù)數(shù)形式,例如,開源軟件項(xiàng)目Apache POI 的“collectValues”方法,將其切分并還原為小寫字母后得到“collect values”動(dòng)賓短語,這里面的“values”為復(fù)數(shù)形式,需要還原為原形“value”.本文利用自然語言處理工具包spaCy 將單詞還原為原形.
經(jīng)過上述步驟,即可得到格式統(tǒng)一的基本軟件功能特征名稱.以開源軟件項(xiàng)目Apache POI 中的方法名稱為例,“getDocument”“setBorderColor”“getFirstColumn”等在表現(xiàn)形式方面都是按照小駝峰式命名的,在自然語言含義方面分別表達(dá)了獲取文件(get document)、設(shè)置邊界顏色(set border color)、獲取第1 列(get the first column)的含義,使開發(fā)人員可以一目了然這些方法的功能.
本文從源代碼的代碼元素中進(jìn)一步提取軟件概念,用以輔助復(fù)合軟件功能特征名稱的挖掘.這里,軟件概念指的是與軟件項(xiàng)目相關(guān)的名詞,是軟件功能潛在的操作對(duì)象.軟件概念的挖掘采用迭代擴(kuò)充的算法,流程中主要分為軟件概念的擴(kuò)充和軟件概念的過濾這兩個(gè)步驟.初始時(shí),由代碼元素中的類名組成種子概念集合.
2.2.1 軟件概念的擴(kuò)充
本文基于軟件項(xiàng)目源代碼中的類間關(guān)系和類中的內(nèi)容擴(kuò)充種子概念,從而得到軟件項(xiàng)目的候選概念集合.以種子概念為基準(zhǔn),針對(duì)以Java 為例的面向?qū)ο缶幊陶Z言,本文設(shè)計(jì)了如表1 所示的軟件概念的擴(kuò)充規(guī)則.
Table 1 Rules for extracting new software terms表1 新軟件概念的抽取規(guī)則
本文設(shè)計(jì)的軟件概念的擴(kuò)充規(guī)則具體說明如下.
R1 基于extends 關(guān)鍵字進(jìn)行擴(kuò)充.該關(guān)鍵字用來表示兩個(gè)類之間的繼承關(guān)系.如果類C1繼承自類C2,則C2就是一個(gè)新的軟件概念.例如,“Picture extends Shape”語句表示Picture 類繼承自Shape 類,以種子概念“Picture”為基準(zhǔn),就得到了新的軟件概念“Shape”.
R2 基于implements關(guān)鍵字進(jìn)行擴(kuò)充.該關(guān)鍵字意味著一個(gè)類實(shí)現(xiàn)了一個(gè)接口,也用來表示繼承關(guān)系.如果類C1實(shí)現(xiàn)了接口 I,那么 I 就是一個(gè)新的軟件概念.例如,“BooleanFunction implements Function”語句表示BooleanFunction 類實(shí)現(xiàn)了 Function 接口,以種子概念“BooleanFunction”為基準(zhǔn),就得到了新的軟件概念“Function”.
R3 基于類中的get/set 方法進(jìn)行擴(kuò)充.如果類C1中有g(shù)et/set 方法,那么get/set 方法名中去掉“get”“set”前綴的對(duì)象就是一個(gè)新的軟件概念.例如,HSSFCell 類中包含getCellType 和setCellType 方法,那么去掉“get”“set”前綴就得到了新的軟件概念“CellType”.
根據(jù)以上3 條規(guī)則,將種子概念集合進(jìn)行擴(kuò)充,就得到了候選軟件概念集合.如果當(dāng)前的候選軟件概念集合與種子概念集合相比沒有新增數(shù)據(jù),即可結(jié)束軟件概念的挖掘流程,當(dāng)前的候選軟件概念集合即為該軟件項(xiàng)目概念挖掘的最終結(jié)果;否則,按照后文所述對(duì)候選軟件概念集合進(jìn)行過濾,并將過濾結(jié)果重新作為種子概念集合,迭代挖掘出軟件概念.
2.2.2 軟件概念的過濾
上文得到的候選軟件概念集合中可能會(huì)存在與具體的軟件項(xiàng)目無關(guān)或者無意義的詞語,因此,每次依據(jù)擴(kuò)充規(guī)則得到新的候選軟件概念集合之后,就需要對(duì)該候選集合進(jìn)行過濾.過濾主要依據(jù)以下兩條規(guī)則.
1) 去除表示基本數(shù)據(jù)類型的候選概念.以Java 編程語言為例,它具有char、boolean、byte、short、int 等基本數(shù)據(jù)類型.這些基本數(shù)據(jù)類型與具體的軟件項(xiàng)目并無關(guān)聯(lián),是編程語言中的普遍概念,因此,在挖掘軟件項(xiàng)目相關(guān)概念時(shí)應(yīng)當(dāng)被過濾掉.
2) 去除無意義的詞語.例如,在開源軟件項(xiàng)目Apache POI 的CTOfficeArtExtension 類中包含getAny 和setAny 方法,依據(jù)上一節(jié)中的擴(kuò)充規(guī)則,會(huì)得到新的軟件概念“Any”.但是,“Any”意為任何一個(gè),并不是一個(gè)有明確意義的詞匯,因此應(yīng)當(dāng)被過濾掉.
根據(jù)以上兩條規(guī)則對(duì)候選軟件概念集合進(jìn)行過濾,過濾結(jié)果即可作為下一輪迭代挖掘的種子概念集合.重復(fù)上述擴(kuò)充-過濾的過程,直到概念集合不再變換為止.
基于軟件概念,本文選取目前最大的問答論壇Stack Overflow 作為具體數(shù)據(jù)來源,從軟件文檔問答文檔中提取相關(guān)動(dòng)賓短語.具體的挖掘過程主要分為文本提取與句法分析、動(dòng)賓短語篩選和軟件功能特征名稱合并這3 個(gè)步驟.
2.3.1 文本提取與句法分析
在Stack Overflow 討論帖中,有問題、回答和討論3 部分內(nèi)容.問題中描述了作者的疑問,也是討論帖的主題.回答可能會(huì)有多個(gè),作者可以選擇接受其中的一個(gè)高質(zhì)量的正確的回答,未被接受的回答通常都是不正確的或者描述不清楚的.討論中的語言較為日常化,而且涉及的內(nèi)容并不是針對(duì)問題的解答.因此,為了獲得正確且高質(zhì)量的數(shù)據(jù),本文只考慮問題和作者接受的回答中的文本片段.
為了提取出文本片段,本文利用BeautifulSoup 來提取Stack Overflow 討論帖的文本內(nèi)容.BeautifulSoup 是一個(gè)可以將HTML 文件轉(zhuǎn)換成復(fù)雜的樹形結(jié)構(gòu)并進(jìn)而提取數(shù)據(jù)的Python 庫.接下來,利用自然語言處理工具包spaCy 來提取文本內(nèi)容中的動(dòng)賓短語.具體包括3 個(gè)步驟:(1) 將文本片段解析為AST.(2) 遍歷AST,提取出動(dòng)賓短語.(3) 將動(dòng)賓短語中的動(dòng)詞還原成原形.動(dòng)詞可能為第3 人稱單數(shù)或者過去式或者現(xiàn)在分詞,需要還原為統(tǒng)一的形式.由此,我們得到了每個(gè)討論帖中的動(dòng)賓短語,從而得到整個(gè)軟件項(xiàng)目的動(dòng)賓短語集合.
2.3.2 動(dòng)賓短語的篩選
在上述動(dòng)賓短語集合中,并非所有動(dòng)賓短語描述的都是軟件功能.通常在如下兩種情況下動(dòng)賓短語與軟件功能無關(guān).
(1) 動(dòng)賓短語描述的可能是問答論壇場(chǎng)景中的動(dòng)作,比如在Stack Overflow 討論帖中,“cause problem”“believe me”“share answer”“follow tips”等動(dòng)賓短語描述的都是由人來完成的事情,都是與軟件項(xiàng)目的功能無關(guān)的.
(2) 動(dòng)賓短語使用一些沒有明確指向意義的詞語或者并非軟件項(xiàng)目特定場(chǎng)景下的詞語,使得短語的意義模糊不清或者與特定軟件項(xiàng)目無關(guān).比如,如果動(dòng)賓短語中使用“this”“it”“them”等代詞作為賓語成分,那么無法確定這些代詞的具體含義;如果動(dòng)賓短語中使用“answer”“post”等問答論壇中的常用詞語或者“module”“version”等軟件開發(fā)過程中的普遍用語作為賓語成分,那么也是與特定的軟件項(xiàng)目無關(guān)的.
由以上分析可知,在軟件功能無關(guān)的動(dòng)賓短語中,賓語成分都是與特定軟件項(xiàng)目無關(guān)的詞語.因此,需要對(duì)動(dòng)賓短語集合進(jìn)行篩選,僅保留與軟件項(xiàng)目有關(guān)的動(dòng)賓短語,作為候選復(fù)合軟件功能特征名稱.考慮到代碼標(biāo)示符中常使用單詞的縮寫等形式,直接將賓語成分與軟件概念進(jìn)行匹配會(huì)誤篩一些有意義的動(dòng)賓短語.因此,除了詞根化后的單詞完全匹配外,本文參照已有工作[16]考慮了如下3 種情況.
①軟件概念是賓語成分的首字母縮寫,如“nn”可以匹配“neural network”.
② 軟件概念是賓語成分的前綴,如“doc”可以匹配“document”.考慮到過短的前綴會(huì)造成大量的錯(cuò)誤匹配,實(shí)現(xiàn)中規(guī)定前綴的長度至少為3.
③去除軟件概念和賓語成分的公共前綴/后綴單詞后滿足情況①或情況②,如“neural net”可以匹配“neural network”.
值得注意的是,有些動(dòng)賓短語的賓語成分并不屬于特定軟件項(xiàng)目的概念集合,也不是軟件開發(fā)過程中的普遍用語,而是軟件領(lǐng)域的通用概念.例如,“border”“style”“method”等,以這些通用概念為賓語成分的動(dòng)賓短語也應(yīng)當(dāng)被認(rèn)為與該軟件項(xiàng)目有關(guān).本文基于軟件開發(fā)和問答論壇場(chǎng)景建立停用詞表,并建立軟件領(lǐng)域的通用概念詞表,利用這兩個(gè)詞表和上文挖掘出的軟件概念集合來篩選動(dòng)賓短語,提取出賓語為特定軟件項(xiàng)目相關(guān)概念的動(dòng)賓短語.由此,就得到了候選復(fù)合軟件功能特征名稱集合.以開源軟件項(xiàng)目Apache POI 為例,“add cell”“fill pattern”“resize picture”等動(dòng)賓短語中的賓語“cell”“pattern”“picture”都是該軟件項(xiàng)目的相關(guān)概念,可以作為候選復(fù)合軟件功能特征.
2.3.3 軟件功能特征合并
候選復(fù)合軟件功能特征名稱集合中的元素都是與軟件項(xiàng)目相關(guān)的動(dòng)賓短語,都描述了軟件功能.但是,其中的動(dòng)賓短語可能意義相同或者相近,有兩種情況:(1) 兩個(gè)動(dòng)賓短語的謂語、賓語和約束成分都相同,含義也相同,只是“a”“an”“the”等修飾成分有差異.例如,“adjust the column width”和“adjust column width”都表達(dá)了“設(shè)置列的寬度”的含義,“add hyperlink”和“add a hyperlink”都表達(dá)了“添加超鏈接”的含義.(2) 兩個(gè)動(dòng)賓短語使用的動(dòng)詞不同,但含義相近.例如,“use color”和“apply color”都表達(dá)了“使用顏色”的含義,“hold value”和“keep value”都表達(dá)了“保持值不變”的含義.考慮到上述情況,為了避免同義或者近義復(fù)合軟件功能特征名稱同時(shí)存在產(chǎn)生冗余,本文對(duì)候選復(fù)合軟件功能特征名稱進(jìn)行了合并.
候選復(fù)合軟件功能特征名稱都是以軟件概念為賓語的動(dòng)賓短語.軟件概念集合中的各個(gè)名詞都有其特定的含義,不涉及同義或者近義的問題.因此,在對(duì)動(dòng)賓短語進(jìn)行合并時(shí),僅需要考慮對(duì)于賓語相同的短語,其中的動(dòng)詞成分是否相似、賓語的約束成分是否相同.
本文利用自然語言處理工具集NLTK(Natural Language Toolkit)的WordNet 來計(jì)算動(dòng)詞相似度.在WordNet中,名詞、動(dòng)詞、形容詞和副詞各自被組織成一個(gè)同義詞的網(wǎng)絡(luò),可以通過計(jì)算同一詞性的不同詞語之間的距離來得知它們的語義相似度.該距離為[0,1]之間的一個(gè)數(shù)值,當(dāng)該數(shù)值為1 時(shí),反映了兩個(gè)詞語在一個(gè)同義詞集合中,即兩個(gè)詞語同義.由此,合并候選復(fù)合軟件功能特征名稱的步驟如下.
(1) 將動(dòng)賓短語按照賓語成分分為不同的小集合,每個(gè)小集合中的動(dòng)賓短語都具有相同的賓語成分.
(2) 對(duì)一個(gè)小集合中的動(dòng)賓短語,按照以下兩條規(guī)則判斷任意兩個(gè)動(dòng)賓短語是否相似.如果兩個(gè)動(dòng)賓短語相似,則只保留一個(gè)動(dòng)賓短語,并將與這兩個(gè)動(dòng)賓短語相關(guān)的信息合并.具體判斷規(guī)則是:首先,去掉動(dòng)賓短語中的“a”“an”“the”等修飾成分,只保留謂語、賓語、約束成分,字母全部轉(zhuǎn)化成小寫形式.如果此時(shí)兩個(gè)動(dòng)賓短語完全一致,那么就認(rèn)為兩個(gè)動(dòng)賓短語相似;其次,計(jì)算兩個(gè)動(dòng)賓短語的謂語的相似度,即利用WordNet 計(jì)算兩個(gè)動(dòng)詞是否屬于一個(gè)同義詞集合.如果兩個(gè)動(dòng)賓短語經(jīng)過規(guī)則(1)的處理只有謂語不同,其他成分都相同,而且兩個(gè)動(dòng)賓短語的謂語是同義詞,那么就認(rèn)為兩個(gè)動(dòng)賓短語相似.
按照上述步驟,即可完成相似動(dòng)賓短語的合并,于是就可以得到軟件項(xiàng)目的復(fù)合軟件功能特征集合.
軟件項(xiàng)目具有豐富的功能特征.以開源軟件項(xiàng)目為例,本文方法為Apache POI 挖掘了上萬個(gè)軟件功能特征.如果將軟件功能特征簡單地存儲(chǔ)到集合中,無疑會(huì)對(duì)開發(fā)人員的瀏覽和檢索帶來困難.因此,本文對(duì)軟件功能特征進(jìn)行層次化的組織和展示,形成具有對(duì)象層和功能特征層兩層結(jié)構(gòu)的軟件功能特征視圖,并挖掘視圖中元素之間的關(guān)聯(lián)關(guān)系,以方便開發(fā)人員檢索相關(guān)的功能特征.
軟件功能特征視圖包含兩個(gè)層次:對(duì)象層將軟件功能特征施加的對(duì)象組織在一起,功能特征層將與某個(gè)對(duì)象相關(guān)的軟件功能特征組織在一起.其中,基本軟件功能特征所對(duì)應(yīng)的對(duì)象是功能特征所屬的類的名稱,復(fù)合軟件功能特征所對(duì)應(yīng)的對(duì)象是功能特征名稱中的賓語成分.以開源軟件項(xiàng)目Apache POI 為例,“get anchor”“apply transform”等基本功能特征是“DrawShape”類中的公共調(diào)用接口,因此,這些基本軟件功能特征對(duì)應(yīng)的對(duì)象層元素就是類名“DrawShape”.該軟件項(xiàng)目擁有“access cell”“add cell”“arrange cell”等復(fù)合軟件功能特征名稱,這些功能特征的賓語成分都是“cell”,因此都應(yīng)當(dāng)與“Cell”對(duì)象對(duì)應(yīng).
軟件功能特征視圖中包含3 種關(guān)聯(lián)關(guān)系:(1) 具有功能(“has_function”)是對(duì)象與功能特征之間的關(guān)聯(lián)關(guān)系,表示對(duì)象具有相關(guān)的功能特征,由上文所述的功能特征與對(duì)象的對(duì)應(yīng)規(guī)則來建立;(2) 繼承(“inherits”)是對(duì)象層中的關(guān)聯(lián)關(guān)系,表示一個(gè)對(duì)象繼承自另一個(gè)對(duì)象,由類間的繼承關(guān)系來建立;(3) 來源相同(“from_sam_post”關(guān)聯(lián))是功能特征層中的關(guān)聯(lián)關(guān)系,表示兩個(gè)功能特征來源相同,由功能特征來源于的Stack Overflow 討論帖是否相同來建立.
圖3 展示出:(1) 軟件功能特征視圖的結(jié)構(gòu)示例;(2) 用戶搜索瀏覽軟件功能的工具界面.可以看到,軟件功能特征視圖以一個(gè)軟件概念為根節(jié)點(diǎn),以樹形結(jié)構(gòu)展開軟件概念上的功能(如從“Sheet”概念展開到“create sheet”)以及繼承的子概念(如從“Sheet”概念展開到“HSSFSheet”).用戶在使用網(wǎng)頁工具瀏覽軟件功能特征時(shí),首先指定軟件項(xiàng)目,接著可以用關(guān)鍵詞檢索對(duì)應(yīng)的軟件概念和功能特征,工具提供簡單的補(bǔ)全機(jī)制并推薦3 個(gè)相關(guān)概念和功能,用戶可以點(diǎn)擊檢索項(xiàng)進(jìn)入軟件概念頁面或功能特征頁面.在概念頁面中,除了給出概念名稱和所對(duì)應(yīng)的類/接口名,還展示了當(dāng)前概念所對(duì)應(yīng)的功能特征(對(duì)應(yīng)“has_function”關(guān)聯(lián))以及繼承當(dāng)前類/實(shí)現(xiàn)當(dāng)前接口的概念(對(duì)應(yīng)“inherits”關(guān)聯(lián)).在功能特征頁面,給出了功能特征名稱以及Stack Overflow 上下文中的代碼片段,同時(shí)給出了在同一個(gè)討論貼中出現(xiàn)的其他功能特征(對(duì)應(yīng)“from_same_post”關(guān)聯(lián)).
Fig.3 Example and UI of software functional feature view圖3 軟件功能特征視圖示例和工具界面
為了驗(yàn)證本文工作,我們選取若干開源軟件代碼庫,收集整理了其軟件源代碼、官方文檔以及大量的Stack Overflow 數(shù)據(jù)進(jìn)行實(shí)驗(yàn).在實(shí)驗(yàn)中,重點(diǎn)研究和分析以下幾個(gè)問題.
本文方法獲取的軟件功能特征具有什么特點(diǎn)?是否覆蓋了一個(gè)軟件項(xiàng)目的基本功能?為此,我們針對(duì)特定軟件項(xiàng)目或代碼庫進(jìn)行了功能特征挖掘,并將挖掘結(jié)果與該軟件已有的官方功能文檔進(jìn)行了對(duì)比實(shí)驗(yàn).
針對(duì)Stack Overflow 文檔中出現(xiàn)的功能特征描述,本文方法進(jìn)行軟件功能特征提取的準(zhǔn)確率如何?為此,我們采用人工標(biāo)注方式對(duì)挖掘結(jié)果進(jìn)行了分析,給出了客觀評(píng)價(jià).
與現(xiàn)有工作相比,本文方法的優(yōu)勢(shì)在哪里?從源代碼中提取的軟件概念對(duì)軟件功能特征挖掘過程有哪些改進(jìn)?為此,我們?cè)趯?shí)驗(yàn)中對(duì)比了不同策略的挖掘結(jié)果,并進(jìn)行了實(shí)際數(shù)據(jù)上的驗(yàn)證.
本文選取3 個(gè)開源軟件項(xiàng)目數(shù)據(jù)進(jìn)行了實(shí)驗(yàn)驗(yàn)證,包括Apache POI、Eclipse JDT 和JFreeChart.選擇這3個(gè)軟件項(xiàng)目的主要原因是:(1) 這些軟件項(xiàng)目開源,容易獲取到軟件的源代碼,并且這些軟件項(xiàng)目分別覆蓋不同類型的應(yīng)用領(lǐng)域:Microsoft 文件處理、Java 代碼解析和圖表繪制,可以了解不同領(lǐng)域代碼的特點(diǎn);(2) 這些軟件項(xiàng)目使用比較廣泛,可以從Stack Overflow 問答論壇獲取到大量的討論數(shù)據(jù);(3) 這些軟件項(xiàng)目的官方文檔質(zhì)量較好,可以獲取到更多對(duì)比實(shí)驗(yàn)數(shù)據(jù).例如,Apache POI 軟件項(xiàng)目的功能文檔(https://poi.apache.org/components/spreadsheet/quick-guide.html)以列表的形式展示了常見的功能特征及其代碼示例;Eclipse JDT 在Java 學(xué)習(xí)網(wǎng)站ProgramGreek 上面提供了Eclipse JDT Tutorials(https://www.programcreek.com/2011/01/best-java-developmenttooling-jdt-and-astparser-tutorials/),列出了常見的功能特征及其代碼示例;(4) 實(shí)驗(yàn)評(píng)估人員較為熟悉這些軟件項(xiàng)目,也便于人工標(biāo)注標(biāo)準(zhǔn)數(shù)據(jù)集.
實(shí)驗(yàn)數(shù)據(jù)的具體情況見表2.每個(gè)軟件項(xiàng)目的實(shí)驗(yàn)數(shù)據(jù)包括源代碼、功能文檔和討論帖這3 部分.其中,軟件源代碼來源于GitHub 上軟件項(xiàng)目的最新版本;功能文檔來源于官方網(wǎng)站或者大型學(xué)習(xí)網(wǎng)站;討論帖來源于Stack Overflow 問答論壇.我們分別以“apache-poi”“eclipse-jdt”“jfreechart”為標(biāo)簽下載討論帖,并對(duì)討論帖按照投票數(shù)(vote)進(jìn)行排序,選用投票數(shù)大于0 的討論帖作為實(shí)驗(yàn)數(shù)據(jù).表2 展示了源代碼中包含的類和API 的數(shù)量、功能文檔中包含的功能特征和API 的數(shù)量以及Stack Overflow 討論帖數(shù)量.其中,軟件項(xiàng)目JFreeChart 沒有功能文檔,故未作統(tǒng)計(jì).
Table 2 Statistics for our dataset表2 實(shí)驗(yàn)數(shù)據(jù)集情況
基于上述方法和實(shí)驗(yàn)數(shù)據(jù),本文對(duì)Apache POI、Eclipse JDT 和JFreeChart 這3 個(gè)軟件項(xiàng)目的功能特征進(jìn)行了挖掘.挖掘結(jié)果見表3.以Apache POI 為例,在挖掘過程中我們共計(jì)得到了11 176 個(gè)軟件功能特征,其中包括8 763 個(gè)基本軟件功能特征和2 413 個(gè)復(fù)合軟件功能特征.挖掘過程中,我們從源代碼中獲取的代碼元素包括1 320 個(gè)類和11 943 個(gè)方法,迭代挖掘得到2 072 個(gè)軟件概念,從Stack Oveflow 討論帖中提取了12 786 個(gè)動(dòng)賓短語,其中,2 413 個(gè)動(dòng)賓短語修正、合并成為最終的軟件功能特征.在軟件功能特征視圖中,對(duì)象與功能特征之間建立了11 176個(gè)“has_function”關(guān)聯(lián),對(duì)象之間基于繼承關(guān)系建立了1 081個(gè)“inherits”關(guān)聯(lián),功能特征之間基于來源于相同Stack Overflow 討論帖建立了1 637 個(gè)“from_same_post”關(guān)聯(lián).
Table 3 Statistics for functional feature mining表3 功能特征挖掘總體統(tǒng)計(jì)情況
為了進(jìn)一步分析本文的軟件功能特征挖掘結(jié)果,我們將挖掘得到的功能特征與軟件項(xiàng)目的官方文檔進(jìn)行了對(duì)比分析.對(duì)比評(píng)價(jià)標(biāo)準(zhǔn)見表4.其中,“功能特征”指的是本文方法挖掘出的軟件功能描述;“功能條目”指的是軟件項(xiàng)目功能描述文檔中的軟件功能描述;“代碼片段”指的是功能特征來源于的Stack Overflow 討論帖中所包含的代碼信息;“代碼示例”指的是軟件項(xiàng)目功能描述文檔中的代碼信息.實(shí)驗(yàn)中我們逐一檢視這些軟件功能描述,采用人工評(píng)價(jià)的方式判斷該軟件功能描述是否出現(xiàn)在本文方法的挖掘結(jié)果中.具體地,我們邀請(qǐng)了兩位熟悉實(shí)驗(yàn)中使用的開源項(xiàng)目的開發(fā)者,分別依次判斷是否符合T1~T4 的覆蓋情況,把功能特征首次符合的覆蓋情況作為該功能特征的覆蓋類型.每位開發(fā)者獨(dú)立進(jìn)行判斷,全部完成后對(duì)意見不一致的功能特征統(tǒng)一進(jìn)行評(píng)判.
Table 4 The coverage evaluation criteria in our experiments表4 挖掘結(jié)果與官方文檔中功能特征的評(píng)價(jià)策略
表5 描述了針對(duì)上述兩個(gè)項(xiàng)目進(jìn)行對(duì)比分析的結(jié)果.其中,Apache POI 軟件官方文檔中包含 Busy Developers’ Guide to Features 等46 個(gè)功能條目.從表中可以看到,該項(xiàng)目評(píng)價(jià)為功能特征與功能條目具有相同的名稱(T1)和功能特征與功能條目具有相同的含義但描述方式不同(T2)的功能特征共計(jì)占比69.57%,4 種覆蓋類型總共占比95.65%.而在Eclipse JDT 的19 個(gè)功能條目中,評(píng)價(jià)為功能特征與功能條目具有相同的名稱(T1)和功能特征與功能條目具有相同的含義但描述方式不同(T2)的功能特征共計(jì)占比52.63%,4 種覆蓋類型總共占比也達(dá)到了94.74%.綜合兩個(gè)軟件項(xiàng)目可以得出,本文方法對(duì)功能描述文檔中列舉的常用軟件功能達(dá)到了95.38%的覆蓋率.
Table 5 Results for coverage evaluation表5 挖掘結(jié)果對(duì)官方功能文檔的覆蓋率情況
在Apache POI 的功能描述文檔中,有兩個(gè)功能條目沒有出現(xiàn)在本文方法挖掘出的軟件功能特征列表中.經(jīng)過觀察、分析后發(fā)現(xiàn),其中一個(gè)功能條目在Stack Overflow 問答網(wǎng)站上沒有相關(guān)的討論記錄,因此無法挖掘出來;另一個(gè)功能條目的相關(guān)信息僅在非接受回答(acc_answer)中出現(xiàn)了1 次,非接受回答相當(dāng)于沒有受到討論帖作者的認(rèn)可,根據(jù)本文對(duì)討論帖中內(nèi)容的質(zhì)量和正確性的考量,不考慮非接受回答中的內(nèi)容,因此也無法挖掘出來.而在Eclipse JDT 的功能描述文檔中,僅有一個(gè)功能條目沒有出現(xiàn)在本文方法挖掘出的軟件功能特征列表中.調(diào)研結(jié)果表明,由于該功能條目在Stack Overflow 問答網(wǎng)站上也沒有相關(guān)的討論記錄,因此無法挖掘出來.
本文實(shí)驗(yàn)從Apache POI、Eclipse JDT 和JFreeChart 這3 個(gè)軟件項(xiàng)目的討論帖中分別提取了13 993、2 057和5 968 個(gè)語句,要逐一分析每個(gè)語句挖掘結(jié)果是不現(xiàn)實(shí)的.為此,我們從各個(gè)項(xiàng)目的討論帖中分別隨機(jī)抽取300個(gè)語句,由熟悉這3 個(gè)軟件項(xiàng)目的開發(fā)人員人工標(biāo)注每個(gè)語句中出現(xiàn)的軟件功能特征,作為標(biāo)準(zhǔn)數(shù)據(jù)對(duì)照集.為了避免人工選取動(dòng)賓短語帶來的誤差,我們實(shí)現(xiàn)用spaCy 工具抽取了句子中的動(dòng)賓短語,標(biāo)注時(shí)僅需要選擇符合標(biāo)準(zhǔn)的動(dòng)賓短語,而非人工截取句中的動(dòng)賓短語.為避免標(biāo)注錯(cuò)誤,只有同時(shí)被3 位人員標(biāo)注為功能特征的動(dòng)賓短語才被保留.標(biāo)準(zhǔn)數(shù)據(jù)集中軟件功能特征的分布情況如圖4 所示.各個(gè)軟件項(xiàng)目的語句中的功能特征分布情況大致相同:大部分實(shí)驗(yàn)語句中包含0 個(gè)軟件功能特征,即語句中沒有提及軟件功能相關(guān)的信息;少部分(幾十個(gè))語句中提及1 個(gè)軟件功能特征;極少量(不足10 個(gè))實(shí)驗(yàn)語句中提及2 個(gè)或3 個(gè)軟件功能特征;沒有語句提及4 個(gè)及以上軟件功能特征.
之后,我們請(qǐng)構(gòu)造標(biāo)準(zhǔn)對(duì)照數(shù)據(jù)集的3 位開發(fā)人員瀏覽本文方法生成的功能特征列表,并對(duì)其中每個(gè)條目的準(zhǔn)確性進(jìn)行評(píng)判.對(duì)于實(shí)驗(yàn)數(shù)據(jù)中的每個(gè)語句,如果人工標(biāo)注的軟件功能特征集合與本文方法挖掘出的軟件功能特征集合完全一致,則認(rèn)為本文方法對(duì)該語句的挖掘結(jié)果是正確的.實(shí)驗(yàn)結(jié)果見表6.
從表6 可以看到,在人工標(biāo)注的標(biāo)準(zhǔn)數(shù)據(jù)集中,實(shí)驗(yàn)人員平均為每個(gè)軟件項(xiàng)目的300 個(gè)語句標(biāo)注了76.00 個(gè)功能特征.在本文方法的語句挖掘結(jié)果中,為Apache POI 軟件項(xiàng)目中的276 個(gè)語句正確挖掘出了對(duì)應(yīng)的功能特征,為Eclipse JDT 和JFreeChart 軟件項(xiàng)目中的284 個(gè)語句正確挖掘出了對(duì)應(yīng)的功能特征,平均的挖掘正確率達(dá)到了93.78%.在軟件功能特征挖掘結(jié)果中,為Eclipse JDT 軟件項(xiàng)目挖掘58(54+4)個(gè)功能特征,其中,54 個(gè)與人工標(biāo)注相符,4 個(gè)沒有出現(xiàn)在人工標(biāo)注的結(jié)果中,準(zhǔn)確率為93.10%,同時(shí)工具遺漏了12 條人工標(biāo)注的功能特征,挖掘結(jié)果的召回率為81.82%.平均情況下,每個(gè)軟件項(xiàng)目有62.33 個(gè)功能特征挖掘正確,有13.67 個(gè)軟件功能特征被遺漏,有5 個(gè)軟件功能特征提取錯(cuò)誤,功能特征挖掘結(jié)果的召回率和準(zhǔn)確率分別達(dá)到了81.35%和92.57%.
Fig.4 Distribution of functional features in sentences of standard dataset圖4 標(biāo)準(zhǔn)數(shù)據(jù)集的語句中軟件功能特征分布情況
Table 6 Accuracy scores of the generated functional feature list表6 本文方法挖掘結(jié)果與標(biāo)準(zhǔn)數(shù)據(jù)集相比的準(zhǔn)確率評(píng)估結(jié)果
本文綜合利用軟件項(xiàng)目源代碼和Stack Overflow 討論帖來挖掘軟件功能特征,在設(shè)計(jì)挖掘方案時(shí)對(duì)兩部分?jǐn)?shù)據(jù)分別進(jìn)行了考慮:對(duì)于源代碼信息,本文從源代碼中提取API 作為基本軟件功能特征名稱的來源,并從源代碼中挖掘軟件概念以輔助篩選軟件功能特征名稱;對(duì)于Stack Overflow 信息,本文利用自然語言處理工具對(duì)Stack Overflow 討論帖中的文本信息進(jìn)行句法分析,并利用啟發(fā)式規(guī)則篩選出軟件功能特征名稱.為了比較驗(yàn)證本文方法中這兩方面數(shù)據(jù)源的必要性,實(shí)驗(yàn)中我們分別實(shí)現(xiàn)了以單一數(shù)據(jù)源為輸入的功能特征挖掘方法進(jìn)行比較.同時(shí),我們對(duì)比了兩個(gè)現(xiàn)有方法:TaskNav[13]和APITasks[17].TaskNav 方法基于自然語言處理中的實(shí)體識(shí)別技術(shù)選取軟件文檔中的概念詞匯,并基于人工制定的動(dòng)詞白名單對(duì)文檔中出現(xiàn)的動(dòng)賓短語進(jìn)行篩選,從而返回與本文功能特征形式一致的(動(dòng)賓短語形式)的軟件開發(fā)任務(wù).APITasks 的場(chǎng)景與本文一致,即從用戶交流記錄中抽取編程任務(wù)相關(guān)的動(dòng)賓短語,該方法使用3 種過濾規(guī)則(短語的結(jié)構(gòu)、上下文和停用詞)剔除低質(zhì)量的動(dòng)賓短語.對(duì)比時(shí),我們獲取了TaskNav 的網(wǎng)頁工具(http://task-phrases.herokuapp.com)和APITasks 的項(xiàng)目源碼,將數(shù)據(jù)集中的句子依次輸入給這兩種工具,將返回結(jié)果和本文方法輸出一起評(píng)判.綜上,本節(jié)對(duì)比了TaskNav 和APITasks 兩種工具,并對(duì)本文方法的兩個(gè)變種(“只考慮源代碼信息”和“只考慮Stack Overflow 信息”)進(jìn)行了實(shí)驗(yàn),判斷實(shí)驗(yàn)語句集合中可被正確挖掘的句子數(shù)量,考慮到不同工具在動(dòng)賓短語的形式定義上有細(xì)微區(qū)別,在判定時(shí)我們使用spaCy 工具選取動(dòng)賓短語中的核心動(dòng)詞和核心賓語成分作為比較對(duì)象,只有詞根化后動(dòng)詞、賓語完全一致的動(dòng)賓短語才被認(rèn)定為正確.最終對(duì)比結(jié)果見表7.
從表7 可以看出,TaskNav 方法抽取正確的句子比例較低,一個(gè)重要原因是TaskNav 基于人工指定的動(dòng)詞白名單對(duì)動(dòng)賓短語進(jìn)行篩選,而不同項(xiàng)目之間的領(lǐng)域動(dòng)詞存在差異(如Eclipse-JDT 中的高頻動(dòng)詞“visit”沒有被TaskNav 納入白名單).APITasks 工具雖然制定了3 種過濾策略對(duì)低質(zhì)量動(dòng)賓短語進(jìn)行過濾,但起到主要過濾作用的仍然是簡單的停用詞匹配.與TaskNav 不同,APITasks 給出了動(dòng)詞的過濾黑名單,但同樣面臨著不同領(lǐng)域的動(dòng)詞集合存在差異這一問題.“只考慮代碼信息”和“只考慮Stack Overflow 信息”這兩種方法的平均準(zhǔn)確率都剛好達(dá)到80%,而本文將這兩種方法結(jié)合起來挖掘的準(zhǔn)確率接近94%.因此,本文提出的挖掘方法總體而言效果顯著,兩種數(shù)據(jù)源的融合/挖掘策略也是必要的.
Table 7 Precision scores of approach comparison表7 本文方法比較的準(zhǔn)確率評(píng)估結(jié)果
本文把從軟件項(xiàng)目源代碼中提取出的代碼元素中的類名作為種子概念,基于規(guī)則進(jìn)行迭代擴(kuò)充,得到軟件概念集合.本實(shí)驗(yàn)通過對(duì)比軟件概念迭代擴(kuò)充次數(shù)對(duì)挖掘結(jié)果準(zhǔn)確率的影響來評(píng)估軟件概念迭代挖掘算法的有效性.實(shí)驗(yàn)結(jié)果見表8.
從實(shí)驗(yàn)結(jié)果可以看出,軟件概念迭代擴(kuò)充1 次和迭代擴(kuò)充2 次對(duì)軟件功能特征準(zhǔn)確率的影響沒有差別,這是因?yàn)榈鷶U(kuò)充過程的終止條件是沒有新增的軟件概念,因此,最后一次擴(kuò)充前后的軟件概念集合是相同的,因而對(duì)軟件功能特征準(zhǔn)確率的影響也是相同的.迭代擴(kuò)充2 次后即滿足迭代擴(kuò)充的終止條件,也就是說,在對(duì)軟件概念進(jìn)行1 次擴(kuò)充后即獲得本文方法最終挖掘出的軟件概念集合.這是因?yàn)?本文將軟件項(xiàng)目源代碼中定義的類的名稱都作為種子概念,以此為軟件概念挖掘算法的起點(diǎn).經(jīng)歷第1 次擴(kuò)充規(guī)則后,新增的軟件概念屬于以下兩種情況:(1) 新增的軟件概念所對(duì)應(yīng)的類是在軟件項(xiàng)目源代碼中定義的.由于這些類的名稱在算法初始時(shí)就存在于種子概念集合中,因此后續(xù)的擴(kuò)充不會(huì)因?yàn)檫@些類對(duì)軟件概念集合產(chǎn)生影響.(2) 新增的軟件概念所對(duì)應(yīng)的類不是在軟件項(xiàng)目源代碼中定義的.由于本文方法是依據(jù)源代碼中描述的類的繼承關(guān)系和類中的方法來擴(kuò)充軟件概念的,因此后續(xù)的擴(kuò)充不會(huì)從這些類中挖掘出新的軟件概念.
Table 8 Influence of iterative extraction algorithm on precision of functional feature (%)表8 本文軟件概念迭代擴(kuò)充算法對(duì)軟件功能特征準(zhǔn)確率的影響(%)
從挖掘結(jié)果來看,按照本文規(guī)則將種子概念集合迭代擴(kuò)充得到軟件概念集合,以輔助軟件功能特征的篩選過程,可以將軟件功能特征挖掘結(jié)果的準(zhǔn)確率由87.56%提升為93.78%.因此,本文設(shè)計(jì)的軟件概念迭代擴(kuò)充算法是有效的,對(duì)軟件功能特征挖掘算法的輔助作用是顯著的.
本文方法的思路是從軟件項(xiàng)目源碼中提取領(lǐng)域詞匯,進(jìn)而到文檔交流記錄中過濾出動(dòng)賓短語形式的軟件功能特征.需要指出的是,輸入的數(shù)據(jù)質(zhì)量可能會(huì)影響到本文方法的效果.
首先,本文依賴源碼的標(biāo)識(shí)符具有較豐富的語義信息和規(guī)范的命名風(fēng)格.本文針對(duì)Java 語言常見的駝峰命名進(jìn)行了切詞和概念抽取,該過程可以方便地?cái)U(kuò)展到其他變量命名風(fēng)格(如下劃線分隔).雖然本文方法考慮了縮寫詞等命名習(xí)慣對(duì)概念抽取的影響,但仍會(huì)有一些概念匹配錯(cuò)誤的情況發(fā)生,如拼寫錯(cuò)誤和單詞內(nèi)部的縮寫(context 縮寫成ctx).因此,除了本文提到的啟發(fā)式匹配規(guī)則外,應(yīng)用一些基于共現(xiàn)的統(tǒng)計(jì)方法[16]有可能會(huì)降低本文方法對(duì)命名風(fēng)格的敏感性.
其次,文檔交流記錄的豐富程度會(huì)影響到最終挖掘的功能特征數(shù)量.本文使用Stack Overflow 作為文檔輸入來源,如果一個(gè)項(xiàng)目在該網(wǎng)站上沒有足夠的討論記錄,本文方法就不能生成高質(zhì)量的軟件功能特征.但需要指出的是,本文方法并沒有基于Stack Overflow 對(duì)輸入文檔的格式作特定假設(shè),因此可以較方便地?cái)U(kuò)展到其他類型的交流記錄(項(xiàng)目特定的論壇、郵件列表等).本文使用Stack Overflow 僅僅因?yàn)槠鋽?shù)據(jù)比較規(guī)整,包含大量關(guān)于不同開源項(xiàng)目的討論.同時(shí),由于不需要訓(xùn)練學(xué)習(xí)過程,本文方法的準(zhǔn)確率并不受文檔規(guī)模的影響.
本文的相關(guān)工作主要從各類軟件文檔中抽取軟件的功能描述信息.代表性的工作是Treude 等人[11,13]將開發(fā)任務(wù)定義為描述特定編程操作的動(dòng)賓短語,并提出了一種基于開發(fā)任務(wù)索引和瀏覽軟件官方文檔的方法.基于該方法的工具 TaskNav 可以幫助開發(fā)人員更高效地瀏覽文檔,定位自身復(fù)用需求.該團(tuán)隊(duì)后續(xù)開發(fā)了NLP2Code 工具[18]以Eclipse 插件形式在IDE 中推薦相關(guān)的開發(fā)任務(wù)和示例代碼.朱子驍?shù)热薣17]提出了基于Stack Overflow 數(shù)據(jù)的軟件功能特征挖掘組織方法.該方法沒有考慮源代碼信息,采用自然語言處理與頻繁子圖挖掘的方式獲得軟件功能特征,取得了較好的覆蓋率,但準(zhǔn)確率較低.Panichella 等人[19]以開發(fā)者交流渠道為數(shù)據(jù)來源,為API 類或方法抽取描述信息;Rastkar 等人[20]提出了一種對(duì)郵件、缺陷報(bào)告等軟件交流數(shù)據(jù)生成文本摘要的技術(shù);Wang 等人[21]用監(jiān)督學(xué)習(xí)的方法得到了文檔中描述領(lǐng)域概念的句法模式,進(jìn)而自動(dòng)地從軟件功能文檔中抽取領(lǐng)域概念;Wong 等人[15]開發(fā)的AutoComment 工具從Stack Overflow 上匹配可以作為代碼注釋的語句.考慮到論壇中存在大量與軟件功能無關(guān)的自然語言,該工具采用啟發(fā)式規(guī)則對(duì)語句進(jìn)行過濾,并采用動(dòng)賓短語的形式進(jìn)行總結(jié);類似的工作還包括Silva 等人[22]開發(fā)的CROKAGE 工具,Jiang 等人[23]采用無監(jiān)督學(xué)習(xí)方法開發(fā)的API 教程推薦工具FRAPT,Treude 等人[24]提出的一種挖掘闡述API 使用關(guān)鍵句(insight)的有監(jiān)督學(xué)習(xí)方法SISE 等等.可以看出,從各類軟件數(shù)據(jù)中獲取軟件描述信息的工作已經(jīng)得到了很大的關(guān)注,但這些工作在挖掘軟件功能描述方面仍存在準(zhǔn)確率的問題,且部分工作生成的代碼描述未必是對(duì)軟件功能的描述,只是代碼相似的文本.本文注重從軟件功能角度出發(fā),綜合代碼和Stack Overflow 兩種數(shù)據(jù)源進(jìn)行挖掘,獲得了較好的結(jié)果.
此外,一些工作關(guān)注代碼注釋[16]或代碼總結(jié)[25]的自動(dòng)生成,這些注釋通常同樣包含軟件的功能描述.此類工作具體可分為基于模板的注釋生成和基于機(jī)器翻譯的注釋生成兩種策略.基于模板的代碼注釋生成方法需要首先按照預(yù)定義代碼模式抽取關(guān)鍵代碼信息,包括抽取關(guān)鍵字、抽取關(guān)鍵語句、抽取代碼關(guān)鍵結(jié)構(gòu)、抽取代碼類型信息和抽取上下文信息等.代表性的工作包括:Haiduc 等人提出了從代碼中選擇出的n個(gè)詞以及代碼結(jié)構(gòu)信息作為代碼注釋的方法[26],其后他們又利用VSM 和LSI 抽取代碼中的重要部分作為代碼的總結(jié)[27];SWUM 方法則通過一些規(guī)則識(shí)別代碼中的關(guān)鍵語句,為一個(gè)函數(shù)生成功能性描述[28,29];Moreno 等人提出了基于特定的生成模板為面向?qū)ο笳Z言中的類產(chǎn)生注釋的方法[30];McBurney 等人則提出了一種側(cè)重上下文的注釋生成方法NLG[31],等等.基于機(jī)器翻譯的注釋生成方法將軟件代碼看作字符串序列,采用雙語翻譯的機(jī)器學(xué)習(xí)方法或模型生成自然語言的代碼注釋.選擇代碼中的何種信息用于表示代碼是該問題的關(guān)鍵.一種較為簡單的方法是:將代碼視為單詞序列,并用代碼中出現(xiàn)的單詞序列用于表示代碼并作為模型的輸入.代表性的工作是Iyer 等人提出的基于LSTM 模型和attention 機(jī)制的注釋自動(dòng)生成方法CODE-NN[32].然而這種處理方法必然會(huì)丟失代碼中的結(jié)構(gòu)信息.為此,后續(xù)工作除了利用代碼本身單詞的信息以外,同時(shí)還對(duì)代碼進(jìn)行解析,抽取代碼的結(jié)構(gòu)信息.這些信息大多數(shù)是基于代碼的抽象語法樹獲取,代表性的工作包括Hu 等人提出的自動(dòng)注釋方法DeepCom[33]、Alon 等人提出的Code2seq[34]等等.盡管注釋生成工具同樣可以生成自然語言形式的功能描述,但通常針對(duì)一個(gè)類、方法(含API)或一段邏輯完整的代碼,從用戶場(chǎng)景上與本文針對(duì)軟件項(xiàng)目的功能特征挖掘工作有所不同.在剛接觸一個(gè)軟件項(xiàng)目庫時(shí),獲得一段高質(zhì)量但待解釋的示例代碼并不容易,本文工作能夠幫助新用戶快速瀏覽定位到所需功能.
本文提出了一種融合代碼與文檔的軟件功能特征挖掘方法,挖掘結(jié)果可以幫助開發(fā)人員快速了解待復(fù)用軟件項(xiàng)目的功能特征,提高軟件復(fù)用的效率.該方法以動(dòng)賓短語形式描述一項(xiàng)軟件功能特征,通過迭代挖掘源代碼抽取軟件概念,輔助從源代碼和Stack Overflow 問答文檔中挖掘軟件功能特征,并構(gòu)建層次化的軟件功能特征視圖.我們?cè)诖罅寇浖?xiàng)目數(shù)據(jù)上進(jìn)行了實(shí)驗(yàn).實(shí)驗(yàn)結(jié)果表明,本文方法獲取的軟件功能特征可以覆蓋官方文檔中約95%的軟件常用功能,挖掘結(jié)果中語句和功能特征的準(zhǔn)確率分別達(dá)到了93.78%和92.57%.
我們下一步的工作計(jì)劃包括:研究如何改進(jìn)本文方法中的動(dòng)賓短語提取方法,提高從自然語言文本中提取功能特征動(dòng)賓短語的準(zhǔn)確率;增強(qiáng)本文工具綜合挖掘多種類型的軟件數(shù)據(jù)的能力,例如從開發(fā)者/用戶郵件列表、缺陷追蹤報(bào)告中進(jìn)一步提取相關(guān)的功能特征;在實(shí)驗(yàn)上,將本文方法和工具應(yīng)用到更多的軟件項(xiàng)目和代碼庫中,通過大規(guī)模數(shù)據(jù)進(jìn)行實(shí)例驗(yàn)證.