劉 磊, 王 昊, 孫 凱, 郜山權(quán), 劉宣彤
(1. 吉林大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院, 長春 130012; 2. 外交學(xué)院 英語系, 北京 100037)
Node包管理器NPM是node.js默認(rèn)的, 用JavaScript編寫的軟件包管理系統(tǒng). 開源開發(fā)人員可基于NPM平臺共享或者借用軟件包. 為幫助開發(fā)人員更高效地搜索到所需的軟件包, NPM提供了一種標(biāo)簽搜索機(jī)制, 根據(jù)具體的標(biāo)簽推薦相關(guān)的軟件包. 因此, NPM平臺通常要求開發(fā)人員在發(fā)布或更新軟件包時(shí)為其分配標(biāo)簽. 目前, 主流的標(biāo)簽推薦方法都是利用物體的文本特征實(shí)現(xiàn)標(biāo)簽推薦[1-2], 如EncTagRec++[3]和FastTagRec[4]等. 這些文本特征主要包括Readme文檔或描述文本. 但在NPM軟件包的標(biāo)簽推薦場景下, 包的Readme文檔主要用于介紹包的使用說明和安裝說明等, 這種類型的文本信息對標(biāo)簽推薦的作用較小, 且包的描述信息過短, 表達(dá)的信息不充足. 本文統(tǒng)計(jì)了58 753個(gè)軟件包的描述信息, 統(tǒng)計(jì)結(jié)果表明, 76.7%的包描述文本不超過10個(gè)單詞. 因此, 這些傳統(tǒng)的利用Readme文檔或描述文本的標(biāo)簽方法在NPM軟件包標(biāo)簽推薦場景下性能較差. 為解決傳統(tǒng)方法在NPM軟件包標(biāo)簽推薦場景下的局限性, 本文從包的代碼角度出發(fā)推薦標(biāo)簽. 與Readme文本以及描述文本相比, 包的代碼信息能更直觀和具體地描述包的行為. 此外, 文獻(xiàn)[5]對比了傳統(tǒng)標(biāo)簽推薦方法和深度學(xué)習(xí)標(biāo)簽推薦方法在相同標(biāo)簽工作下的性能, 實(shí)驗(yàn)結(jié)果表明, 選擇合適的深度學(xué)習(xí)方法可能會獲得更有效的結(jié)果. 因此, 本文從包的代碼角度出發(fā), 利用深度學(xué)習(xí)模型為NPM軟件包推薦標(biāo)簽. 首先, 通過程序分析技術(shù)構(gòu)建出NPM軟件包的函數(shù)調(diào)用圖, 利用圖遍歷算法遍歷該函數(shù)調(diào)用圖, 從而將軟件包轉(zhuǎn)化為一組具有語義信息的函數(shù)調(diào)用序列; 其次, 利用seq2seq模型將函數(shù)體字符序列映射為函數(shù)名稱序列[6], 通過訓(xùn)練seq2seq模型將包含語義信息的軟件包函數(shù)調(diào)用序列映射到軟件包的標(biāo)簽序列上, 從而完成標(biāo)簽的推薦工作.
本文采用加入了注意力機(jī)制[1]的seq2seq模型完成NPM軟件包的標(biāo)簽推薦工作. Seq2seq模型[2]是一種將輸入序列映射到輸出序列的深度學(xué)習(xí)模型, 廣泛應(yīng)用于機(jī)器翻譯領(lǐng)域[7-8]. 該模型通常會引入注意力機(jī)制提高模型性能. 在本文提出的標(biāo)簽推薦方法中, 首先利用ECMAScript開發(fā)工具解析NPM軟件包的源代碼, 構(gòu)建出軟件包的函數(shù)調(diào)用圖, 通過圖的深度優(yōu)先遍歷得到一組能反映軟件包功能語義信息的函數(shù)調(diào)用關(guān)系序列, 并用該序列作為seq2seq模型的輸入; 其次, 再訓(xùn)練seq2seq模型, 該模型以軟件包的標(biāo)簽序列作為輸出. 模型訓(xùn)練結(jié)束后, 對于一個(gè)新的軟件包, 訓(xùn)練好的seq2seq模型會將該包的函數(shù)調(diào)用序列映射到一組預(yù)測的標(biāo)簽序列上, 預(yù)測序列中的標(biāo)簽將會作為推薦標(biāo)簽推薦給該軟件包. 圖1為本文方法的整體流程.
圖1 本文方法流程Fig.1 Flow chart of proposed method
數(shù)據(jù)處理部分為標(biāo)簽推薦模型準(zhǔn)備訓(xùn)練數(shù)據(jù), 該部分主要完成以下兩項(xiàng)任務(wù): 1) 將NPM軟件包表示成函數(shù)調(diào)用序列的形式; 2) 抽取軟件包的標(biāo)簽序列信息. 對于任意一個(gè)NPM軟件包p, 經(jīng)過數(shù)據(jù)處理后都會對應(yīng)一組序列對(s,t):p→(s,t), 其中s是p對應(yīng)的函數(shù)調(diào)用關(guān)系序列,t表示p擁有的標(biāo)簽序列.
1.1.1 函數(shù)調(diào)用序列
為將NPM軟件包表示成序列的形式, 本文選擇構(gòu)建包的函數(shù)調(diào)用圖, 遍歷該調(diào)用圖, 從而得到包的函數(shù)調(diào)用序列, 并用該序列作為包的表示. 由于函數(shù)調(diào)用圖能反映包的函數(shù)調(diào)用關(guān)系, 具有軟件包功能相關(guān)的語義信息, 因此用函數(shù)調(diào)用序列表示一個(gè)NPM軟件包合理.
在構(gòu)建函數(shù)調(diào)用圖的過程中, 利用程序靜態(tài)分析技術(shù)解析NPM軟件包的源代碼, 這些代碼是基于JavaScript(JS)語言實(shí)現(xiàn)的. ECMAScript開發(fā)工具可以幫助解析JS代碼, 其中Esprima為JS代碼生成對應(yīng)的抽象語法樹, Estravese用于遍歷語法樹并定位到函數(shù)相關(guān)的節(jié)點(diǎn)抽取出函數(shù)名稱. 由于一個(gè)NPM包由多個(gè)文件模塊組成, Madge工具用于幫助分析模塊之間的依賴關(guān)系決定模塊分析的順序, 因此在整個(gè)分析過程中, 利用information-matching的方法構(gòu)建NPM軟件包的函數(shù)調(diào)用圖. 最后通過圖的深度優(yōu)先遍歷, NPM軟件包最終被表示成函數(shù)調(diào)用序列的形式.
利用Estraverse工具遍歷抽象語法樹時(shí), 首先需定位語法樹中函數(shù)相關(guān)的節(jié)點(diǎn)才能抽取對應(yīng)的函數(shù)名稱. 函數(shù)相關(guān)的節(jié)點(diǎn)主要是函數(shù)聲明和函數(shù)調(diào)用, 而在JS語言中函數(shù)聲明和函數(shù)調(diào)用的格式有很多種, 其在語法樹中的表現(xiàn)形式也不同. 因此, 為能準(zhǔn)確定位到函數(shù)相關(guān)節(jié)點(diǎn)抽取出的函數(shù)名稱, 本文參考了JS函數(shù)的基礎(chǔ)語法和Esprima官方文檔, 針對不同語法格式的函數(shù)聲明和函數(shù)調(diào)用制定相應(yīng)的抽取規(guī)則定位語法樹中函數(shù)相關(guān)的節(jié)點(diǎn), 從而抽取出函數(shù)名稱及相對應(yīng)的文件模塊信息.
1.1.2 包標(biāo)簽序列
軟件包標(biāo)簽序列的獲取相對容易, CommonJS規(guī)范規(guī)定NPM軟件包的根目錄下必須默認(rèn)存在一個(gè)配置文件package.json, 該配置文件包含了軟件包的基本信息, 其中包括標(biāo)簽信息. 因此, 只需要找到根目錄下的配置文件, 分析配置文件的keywords屬性即可獲取軟件包的標(biāo)簽序列.
收集NPM軟件包對應(yīng)的序列對信息后, 標(biāo)簽推薦模型的輸入和輸出可以確定. 訓(xùn)練時(shí), 模型以軟件包的函數(shù)調(diào)用序列作為輸入, 軟件包的標(biāo)簽序列作為輸出. 訓(xùn)練完成后, 對于一個(gè)新的軟件包的函數(shù)調(diào)用序列, 模型可以預(yù)測一組標(biāo)簽序列, 將該標(biāo)簽序列作為軟件包的推薦標(biāo)簽. 本文方法使用seq2seq模型進(jìn)行標(biāo)簽推薦, 該模型基于編碼器和解碼器構(gòu)建, 編碼器和解碼器均為循環(huán)神經(jīng)網(wǎng)絡(luò)、 長短期神經(jīng)網(wǎng)絡(luò)(LSTM)或門控循環(huán)單元(GRU). 本文選擇計(jì)算能力消耗相對少的GRU循環(huán)神經(jīng)網(wǎng)絡(luò). 為優(yōu)化模型性能, 在seq2seq模型中加入了注意力機(jī)制. 注意力機(jī)制的優(yōu)勢在于該機(jī)制能為模型解碼器端計(jì)算動態(tài)的注意力向量進(jìn)行標(biāo)簽預(yù)測, 這種注意力向量能極大地保留輸入序列的信息, 從而使模型的推薦結(jié)果更準(zhǔn)確合理. 而不采用注意力機(jī)制的seq2seq模型只能基于一個(gè)固定的上下文向量進(jìn)行標(biāo)簽預(yù)測. 這種沒有注意力機(jī)制的模型通常存在兩個(gè)局限性: 1) 當(dāng)輸入序列過長時(shí), 固定的上下文向量很難包含整個(gè)序列的信息, 而是偏向于表達(dá)序列末尾的信息; 2) 使用固定的上下文向量無法幫助模型明確輸入序列和輸出序列之間的對應(yīng)關(guān)系, 使輸入序列中的所有詞匯對預(yù)測結(jié)果的貢獻(xiàn)相同. 這兩種局限性都會影響模型的預(yù)測結(jié)果, 因此本文引入注意力機(jī)制優(yōu)化標(biāo)簽推薦模型. 圖2為標(biāo)簽推薦模型的基本結(jié)構(gòu).
圖2 標(biāo)簽推薦模型結(jié)構(gòu)Fig.2 Architecture of tag recommendation model
對于一個(gè)包p的函數(shù)調(diào)用序列s, 編碼器首先通過嵌入層將s轉(zhuǎn)換成向量的表示形式, 編碼器端的循環(huán)神經(jīng)網(wǎng)絡(luò)利用該向量計(jì)算出不同時(shí)期的隱藏狀態(tài)h.解碼器端在預(yù)測標(biāo)簽時(shí), 會根據(jù)已預(yù)測的標(biāo)簽以及注意力向量計(jì)算當(dāng)前預(yù)測標(biāo)簽yi的概率p,p的計(jì)算公式為
p(yi|y
其中:x為輸入序列的向量表示;y為已預(yù)測標(biāo)簽的向量表示;oi為當(dāng)前解碼器的狀態(tài);ci為當(dāng)前狀態(tài)下的注意力向量, 注意力向量ci是由注意力函數(shù)根據(jù)隱藏狀態(tài)hi和解碼器狀態(tài)oi計(jì)算得到的.在Softmax計(jì)算結(jié)果中最大概率值對應(yīng)的標(biāo)簽為當(dāng)前模型的預(yù)測標(biāo)簽yi.
在數(shù)據(jù)收集過程中, 首先通過爬蟲程序在NPM平臺上收集到3 833個(gè)NPM軟件包的基本信息, 利用命令行安裝指令將這3 833個(gè)包安裝到本地計(jì)算機(jī). 經(jīng)過數(shù)據(jù)處理后, 最終得到3 833條有效的函數(shù)調(diào)用序列信息和標(biāo)簽序列信息對, 這些序列對將用于標(biāo)簽推薦模型的訓(xùn)練和測試. 本文按照傳統(tǒng)的二八劃分將數(shù)據(jù)集劃分為不相交訓(xùn)練集和測試集.
圖3 損失函數(shù)曲線Fig.3 Loss function curve
為使模型表現(xiàn)更優(yōu), 收斂更快, 本文結(jié)合已有的實(shí)現(xiàn)方法設(shè)置seq2seq模型的參數(shù): 學(xué)習(xí)率為0.006, 嵌入層維度為64, 隱藏層神經(jīng)元為1 024, 最大序列長度為100, 損失函數(shù)采用稀疏分類交叉熵. 常用的注意力機(jī)制主要有additive機(jī)制和dot-production機(jī)制兩種, 本文采用后者. 圖3為訓(xùn)練過程中損失函數(shù)值的變化曲線. 由圖3可見, 在迭代到約40輪時(shí)模型已經(jīng)趨于收斂了, 整個(gè)100輪迭代過程約需耗時(shí)70 min.
參考文獻(xiàn)[9], 本文定義兩種指標(biāo)R1和R2評估模型.對于指標(biāo)R1, 只要預(yù)測標(biāo)簽序列與原始標(biāo)簽序列之間交集不為空, 即模型至少預(yù)測對一個(gè)標(biāo)簽即認(rèn)為預(yù)測結(jié)果有效, 統(tǒng)計(jì)有效結(jié)果在測試集中的比例, 該比例作為R1指標(biāo)下的準(zhǔn)確率.其公式定義為
其中:Tp為測試集合;TSO函數(shù)返回包p原始標(biāo)簽序列;TSP函數(shù)返回包p預(yù)測標(biāo)簽序列; 函數(shù)J判斷序列是否有交集, 有交集則返回1, 反之返回0.本文模型在R1評價(jià)指標(biāo)下的準(zhǔn)確率為82.6%.
對于指標(biāo)R2, 只有當(dāng)預(yù)測序列和原始標(biāo)簽序列重合, 即只有當(dāng)模型預(yù)測對所有的標(biāo)簽才能認(rèn)定當(dāng)前預(yù)測結(jié)果有效, 統(tǒng)計(jì)有效結(jié)果在測試集中的比例, 該比例作為R2指標(biāo)下的準(zhǔn)確率.其公式定義為
其中: 函數(shù)F判斷序列是否重合, 重合則返回1, 反之返回0; 其他參數(shù)含義與R1相同.本文模型在R2評價(jià)指標(biāo)下的準(zhǔn)確率為33.7%.由于R2指標(biāo)要求模型完全預(yù)測標(biāo)簽, 所以該準(zhǔn)確率也合理.
圖4為部分軟件包原始標(biāo)簽序列與預(yù)測標(biāo)簽序列的對比結(jié)果. 由圖4可見, 本文模型的確能為軟件包推薦合理的標(biāo)簽, 驗(yàn)證了本文方法的有效性. 盡管本文方法能為NPM軟件包推薦合理的標(biāo)簽, 但由實(shí)驗(yàn)結(jié)果可見, 這種推薦方法存在一定的缺陷, 如在預(yù)測標(biāo)簽序列中會出現(xiàn)重復(fù)的標(biāo)簽, 這與實(shí)際情況不符. 出現(xiàn)這種情況的原因是模型在預(yù)測當(dāng)前標(biāo)簽時(shí)只計(jì)算了輸出序列中每個(gè)標(biāo)簽的概率值, 輸出最大概率值對應(yīng)的標(biāo)簽, 而未考慮該標(biāo)簽是否已經(jīng)出現(xiàn)在輸出序列中了.
圖4 原始標(biāo)簽序列與預(yù)測標(biāo)簽序列對比結(jié)果Fig.4 Comparison results of original tag sequences and predicted tag sequences
綜上所述, 針對NPM平臺上存在大量的軟件包沒有標(biāo)簽或標(biāo)記不完善的問題, 本文提出了一種基于seq2seq模型的標(biāo)簽推薦方法. 該方法從NPM軟件包的源代碼出發(fā), 利用靜態(tài)程序分析技術(shù)構(gòu)建出軟件包的函數(shù)調(diào)用圖, 通過圖遍歷算法將其轉(zhuǎn)換成一組語義信息的函數(shù)調(diào)用序列. 訓(xùn)練好的seq2seq模型將軟件包的函數(shù)調(diào)用序列映射到一組預(yù)測的標(biāo)簽序列上, 從而完成軟件包的標(biāo)簽推薦工作. 實(shí)驗(yàn)結(jié)果表明, 本文方法能為NPM軟件包推薦合理的標(biāo)簽, 準(zhǔn)確率可達(dá)82.6%.