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