孫 凱, 劉宣彤, 張 莉, 劉華虓, 王 禹, 郜山權(quán)
(1. 吉林大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院, 長(zhǎng)春 130012; 2. 外交學(xué)院 英語系, 北京 100037;3. 白城醫(yī)學(xué)高等??茖W(xué)校 信息化學(xué)院, 吉林 白城 137000)
目前, JavaScript編程語言已廣泛應(yīng)用于Web瀏覽器和服務(wù)器上[1], 為幫助開發(fā)者分享和重用代碼, npm(node package manager)不僅是管理JavaScript第三方庫(kù)的管理工具, 同時(shí)也已成為分享代碼的開源平臺(tái). 隨著npm包(第三方庫(kù))的不斷發(fā)展, 越來越多的軟件系統(tǒng)依賴于npm包所提供的多樣且高效的功能.
當(dāng)開發(fā)者需要一個(gè)合適的npm包滿足開發(fā)需求時(shí), 其龐大的數(shù)量使開發(fā)者需耗費(fèi)大量的時(shí)間用于搜索. 而標(biāo)簽作為簡(jiǎn)潔、 直觀的描述方式, 為開發(fā)者在搜索過程中提供了有效的幫助[2]. 開發(fā)者不僅可通過瀏覽標(biāo)簽快捷地獲得包的描述信息, 而且可通過點(diǎn)擊標(biāo)簽獲得與該標(biāo)簽相關(guān)的所有包, 即通過使用標(biāo)簽縮小搜索的范圍[3]. 包的創(chuàng)建者為創(chuàng)建的包打上恰當(dāng)?shù)臉?biāo)簽可提高其被索引到的概率, 從而被更多的開發(fā)者使用. 但有超過40%的npm包沒有標(biāo)簽, 而且由于賦予標(biāo)簽的方式和標(biāo)簽的內(nèi)容都具有極大的自由度, 使得一些包的標(biāo)簽質(zhì)量較低, 無法具有展示包功能的作用.
因此, 本文提出一種為npm包推薦標(biāo)簽的自動(dòng)化方法. 首先, 對(duì)npm平臺(tái)中現(xiàn)有的標(biāo)簽進(jìn)行分析, 根據(jù)標(biāo)簽內(nèi)容與彼此之間的相關(guān)程度解決標(biāo)簽同義問題, 建立標(biāo)簽庫(kù); 其次, 利用包的Readme文檔進(jìn)行詞向量的訓(xùn)練, 借助詞向量挖掘出包的描述文本與標(biāo)簽庫(kù)中標(biāo)簽的聯(lián)系; 最后, 由計(jì)算得到的關(guān)聯(lián)程度進(jìn)行排序生成標(biāo)簽推薦列表, 完成標(biāo)簽推薦工作.
本文首先分析npm社區(qū)中已存在的標(biāo)簽, 用關(guān)聯(lián)關(guān)系挖掘算法構(gòu)建標(biāo)簽關(guān)聯(lián)關(guān)系網(wǎng)絡(luò)圖, 并利用社區(qū)檢測(cè)算法將標(biāo)簽聚成社區(qū), 在每個(gè)標(biāo)簽社區(qū)中, 整合具有相同語義的標(biāo)簽, 以解決標(biāo)簽同義的問題并生成標(biāo)簽庫(kù); 然后利用word2vec技術(shù)將npm包的Readme文件作為訓(xùn)練文本進(jìn)行詞向量的訓(xùn)練; 最后根據(jù)得到的標(biāo)簽庫(kù)與生成的詞向量, 給定一個(gè)沒有標(biāo)簽的npm包, 以計(jì)算其Readme中的單詞詞向量與標(biāo)簽庫(kù)中標(biāo)簽的相關(guān)度, 生成標(biāo)簽推薦列表. 方法流程如圖1所示.
圖1 方法流程Fig.1 Flow chart of method
由于npm包的創(chuàng)建者可自由地為其包打上任意內(nèi)容、 任意數(shù)量的標(biāo)簽, 無任何約束, 從而導(dǎo)致npm社區(qū)的標(biāo)簽數(shù)量龐大, 種類繁多, 卻沒有一致性[4]. 標(biāo)簽作為展示包特點(diǎn)的窗口, 應(yīng)具有簡(jiǎn)潔、 直觀、 易懂的特點(diǎn)[5], 但打標(biāo)簽是一個(gè)具有分布式特點(diǎn)且不協(xié)調(diào)的過程, 使得npm社區(qū)出現(xiàn)很多冗余的標(biāo)簽. 為達(dá)到推薦恰當(dāng)標(biāo)簽的目的, 本文首先對(duì)現(xiàn)有標(biāo)簽進(jìn)行分析整合, 構(gòu)建一個(gè)合理的標(biāo)簽庫(kù).
在現(xiàn)有標(biāo)簽中, 一些標(biāo)簽的出現(xiàn)率極低, 因?yàn)檫@些標(biāo)簽具有定制化的特性, 只適合于所屬項(xiàng)目. 但主要還是因?yàn)檫@些標(biāo)簽的內(nèi)容很難使大多數(shù)開發(fā)者認(rèn)同, 無法得到廣泛使用. 此外, 很多標(biāo)簽是以不同的語法形式表達(dá)相同的語義, 如log,logs和logging都是指代日志功能. 同一單詞的不同語法形式導(dǎo)致標(biāo)簽的冗余, 從而在通過標(biāo)簽進(jìn)行搜索的管理過程中造成不便. 對(duì)于以單詞作為內(nèi)容呈現(xiàn)的標(biāo)簽, 除上述語法問題外, 還存在單詞縮寫和單詞同義問題, 這些問題統(tǒng)稱為標(biāo)簽同義詞問題[6].
定義1標(biāo)簽句TagSentence可定義為對(duì)于存在標(biāo)簽的npm包p, 所屬于p的所有經(jīng)過詞干提取和詞形還原的標(biāo)簽{t1,t2,…,tn}構(gòu)成的標(biāo)簽集.
定義2標(biāo)簽關(guān)聯(lián)關(guān)系ti?tj可定義為對(duì)于兩個(gè)標(biāo)簽ti和tj, 若存在由關(guān)聯(lián)關(guān)系挖掘算法[7]得到的Lift(ti?tj)大于閾值threshold, 則認(rèn)定兩標(biāo)簽構(gòu)成關(guān)聯(lián)關(guān)系:
其中confidence(ti?tj)計(jì)算擁有這兩個(gè)標(biāo)簽的標(biāo)簽句占只含有標(biāo)簽ti的標(biāo)簽句比例, support(ti)計(jì)算標(biāo)簽ti出現(xiàn)在所有標(biāo)簽句中的次數(shù), #tagSent表示tagSentence的數(shù)量.
定義3標(biāo)簽關(guān)聯(lián)圖G〈V,E〉定義為對(duì)于標(biāo)簽關(guān)聯(lián)關(guān)系ti?tj, 標(biāo)簽ti,tj作為圖G〈V,E〉中以無向線段連接的兩個(gè)節(jié)點(diǎn), 所有存在標(biāo)簽關(guān)聯(lián)關(guān)系的標(biāo)簽構(gòu)成節(jié)點(diǎn)集V, 其關(guān)聯(lián)關(guān)系構(gòu)成邊集E.
圖2為標(biāo)簽關(guān)聯(lián)圖的樣例.本文利用關(guān)聯(lián)社區(qū)檢測(cè)方法[8], 使位于同一社區(qū)內(nèi)的標(biāo)簽具有相同顏色.通過人工觀察標(biāo)簽關(guān)聯(lián)圖, 找出擁有相同語義的標(biāo)簽歸為一類, 在每類中選擇出現(xiàn)頻率最高的標(biāo)簽作為代表標(biāo)簽構(gòu)建成標(biāo)簽庫(kù)TL={T1,T2,…,Tn}.
圖2 標(biāo)簽關(guān)聯(lián)圖樣例Fig.2 Sample of a tag correlation graph
npm包的Readme文檔詳細(xì)地給出了包的功能、 使用方法、 安裝環(huán)境等信息, 所以可利用Readme文檔中描述功能的文本計(jì)算與標(biāo)簽的關(guān)聯(lián). 本文將Readme描述功能的文本作為訓(xùn)練數(shù)據(jù), 利用skip-gram模型[9]得到的詞向量完成后續(xù)的標(biāo)簽關(guān)聯(lián)度計(jì)算過程.
標(biāo)簽是對(duì)每個(gè)npm包的總結(jié)概述或描述其所擁有的特性, 而這些內(nèi)容開發(fā)者也可通過閱讀包的Readme 文檔得到, 因此可通過挖掘Readme文檔中的相關(guān)信息實(shí)現(xiàn)推薦標(biāo)簽. 由于包的Readme文檔所呈現(xiàn)的內(nèi)容角度多(簡(jiǎn)介、 使用方法、 參與者等)且形式多樣(文字、 圖片、 表格等), 而只有介紹包功能的描述文本才是挖掘的對(duì)象, 所以本文首先對(duì)Readme文檔進(jìn)行處理, 抽取其中介紹包功能的描述文本并進(jìn)行預(yù)處理. 研究表明, 大多數(shù)包Readme文檔的第一章文字都是介紹包的主要功能和特性[10], 這與標(biāo)簽所展示的內(nèi)容相符, 所以抽取這部分內(nèi)容作為可利用的描述文本.
定義4Readme Token序列Lp定義為對(duì)包p原始Readme文檔描述文本Dp移除其中的圖片、 表格及超鏈接后, 再進(jìn)行分詞、 詞干提取及詞形還原得到的單詞序列.
圖3 Skip-gram模型Fig.3 Skip-gram model
詞向量是對(duì)單詞的低維向量表示, 其建立在具有相似含義的單詞在相似上下文中呈現(xiàn)的假設(shè)上. 單詞的詞向量可捕捉到單詞在文中的語義信息, 即可以使用詞向量比較單詞之間的語義相似度[11]. skip-gram模型[12]是一種高效的學(xué)習(xí)詞向量方法, 該模型由一個(gè)簡(jiǎn)單的3層神經(jīng)網(wǎng)絡(luò)組成, 包括輸入層、 隱藏層和輸出層, 如圖3所示, 其中w(t)是中心詞, 也稱為給定輸入詞.首先, 隱藏層執(zhí)行權(quán)重矩陣和輸入向量w(t)之間的點(diǎn)積運(yùn)算; 其次, 隱藏層中的點(diǎn)積運(yùn)算結(jié)果被傳遞到輸出層; 最后, 輸出層計(jì)算隱藏層輸出向量和輸出層權(quán)重矩陣之間的點(diǎn)積, 再用Softmax激活函數(shù)[13]計(jì)算在給定上下文位置中單詞出現(xiàn)在w(t)上下文中的概率.通過skip-gram算法, 每個(gè)單詞都會(huì)得到一個(gè)詞向量. 某個(gè)詞在句子中的位置與中心詞的位置越近, 則通過skip-gram 算法獲得該詞的詞向量與中心詞的詞向量在向量空間中越接近, 即詞向量間的關(guān)系反映了詞在句子中的密切程度[14].
定義5詞向量Vw定義為以Readme Token序列R形式為樣本的訓(xùn)練集在skip-gram模型中訓(xùn)練得到的關(guān)于單詞w的向量.
由于標(biāo)簽是以單詞的形式對(duì)npm包進(jìn)行概括性地描述, 使得同樣具有描述功能且更詳細(xì)的Readme文檔中的描述文本會(huì)覆蓋標(biāo)簽的內(nèi)容, 即標(biāo)簽會(huì)出現(xiàn)在Readme文檔中. 因此, 詞向量Vw也可作為以單詞w為內(nèi)容的標(biāo)簽T的向量, 記為VT.
本文通過計(jì)算描述文本中的單詞與標(biāo)簽庫(kù)中標(biāo)簽的詞向量相似度建立兩者之間的聯(lián)系, 再對(duì)取得聯(lián)系的標(biāo)簽進(jìn)行排序, 最終挑選出合適的標(biāo)簽進(jìn)行推薦. 詞向量的語義相似度可捕捉到文本中單個(gè)單詞與標(biāo)簽的關(guān)聯(lián)程度, 而描述文本由許多單詞組成, 對(duì)所有單詞進(jìn)行相似度的計(jì)算即能捕獲整個(gè)描述文本與標(biāo)簽的關(guān)聯(lián)程度. 但單詞在描述文本中出現(xiàn)的頻次在一定程度上影響了文本的主題, 因此本文考慮詞頻對(duì)標(biāo)簽相關(guān)度的影響, 從而更準(zhǔn)確地計(jì)算描述文本與標(biāo)簽的關(guān)聯(lián)程度. 算法描述如下:
步驟1) 抽取Readme文檔中的描述文本Dp并進(jìn)行預(yù)處理, 生成 Token序列Lp;
步驟2) 對(duì)Token序列Lp中每個(gè)單詞w的詞向量Vw與標(biāo)簽庫(kù)中每個(gè)標(biāo)簽T的詞向量VT進(jìn)行語義相似度的計(jì)算, 結(jié)果為Sw,T;
步驟3) 由單詞w在Token序列Lp中的詞頻TF(w)與Sw,T的乘積得到關(guān)于詞頻的相關(guān)度Rw,T, 并將結(jié)果按對(duì)應(yīng)的標(biāo)簽進(jìn)行累加, 最終生成每個(gè)標(biāo)簽與描述文本Dp的關(guān)聯(lián)程度RT;
步驟4) 根據(jù)標(biāo)簽與描述文本的相關(guān)程度RT進(jìn)行排序, 得到標(biāo)簽推薦列表;
步驟5) 推薦排名前k的標(biāo)簽.
算法1RT.
輸入: ReadmeRpof npm packagep; Tag LibraryTL={T1,T2,…,Tn};
輸出: topktags;
1) Extract descriptionDpfromRp;
2) Generate token listLpby preprocessingDp;
3) forw∈Lpdo
4) forT∈TLdo
5)Sw,T=Similarity(Vw,VT);
6)Rw,T=Sw,T×TF(w);
7)RT=RT+Rw,T;
8) end for;
9) end for;
10) rank the tags according toRT;
11) return the topktags.
在構(gòu)建標(biāo)簽庫(kù)和訓(xùn)練詞向量?jī)蓚€(gè)步驟中, 都需要可靠的數(shù)據(jù)樣本作為數(shù)據(jù)集. 本文在選取實(shí)驗(yàn)數(shù)據(jù)集時(shí)進(jìn)行如下操作:
1) 考慮到現(xiàn)有標(biāo)簽數(shù)量龐大, 且很多標(biāo)簽利用率極低, 本文選擇最流行的8 000個(gè)包作為樣本;
2) 根據(jù)對(duì)npm包的質(zhì)量、 流行度、 維護(hù)程度的官方評(píng)價(jià)指標(biāo), 本文選擇在樣本中綜合評(píng)分在60分以上的包作為數(shù)據(jù)集, 以保證實(shí)驗(yàn)數(shù)據(jù)有高質(zhì)量的Readme文檔和標(biāo)簽;
3) 對(duì)標(biāo)簽數(shù)大于10的包進(jìn)行過濾, 這是因?yàn)檫^多的標(biāo)簽對(duì)npm是冗余的, 也無法確定哪些標(biāo)簽必要, 最終數(shù)據(jù)集包含6 753個(gè)npm包;
4) 從數(shù)據(jù)集中隨機(jī)抽取100個(gè)包作為最終的測(cè)試集.
由數(shù)據(jù)集構(gòu)建的標(biāo)簽庫(kù)包含126個(gè)代表標(biāo)簽, 代表標(biāo)簽與其同義標(biāo)簽的部分示例列于表1.
表1 代表標(biāo)簽與其同義標(biāo)簽的部分示例
實(shí)驗(yàn)與兩種最新的針對(duì)開源軟件倉(cāng)庫(kù)進(jìn)行主題推薦的方法進(jìn)行對(duì)比: 文獻(xiàn)[2]提出在Github開源軟件倉(cāng)庫(kù)中利用多種文本信息訓(xùn)練多標(biāo)簽分類器以達(dá)到最好的主題預(yù)測(cè)效果; 文獻(xiàn)[6]提出基于Multinomial Naive Bayes算法對(duì)Github開源軟件倉(cāng)庫(kù)進(jìn)行主題分類以生成推薦主題. 其中兩種對(duì)比方法使用的數(shù)據(jù)集與本文方法一致, 本文進(jìn)行多次實(shí)驗(yàn), 取最好結(jié)果進(jìn)行對(duì)比.
選擇Recall@k作為實(shí)驗(yàn)指標(biāo)[15]. 在推薦方法的評(píng)價(jià)指標(biāo)中, Precision@k和Recall@k是最常用的兩個(gè)指標(biāo), 而Recall@k更符合本文問題的設(shè)定, 定義為
其中n是測(cè)試集的總數(shù), Tagp是包p的實(shí)際擁有標(biāo)簽, Recp是方法為包p推薦的top-k標(biāo)簽.
圖4 實(shí)驗(yàn)結(jié)果Fig.4 Experimental results
圖4為本文推薦標(biāo)簽方法的性能. 實(shí)驗(yàn)結(jié)果表明, 本文方法能完成為npm包推薦標(biāo)簽的工作. 由圖4可見: 推薦得分最高的3個(gè)標(biāo)簽時(shí), Recall@3為49.1%; 推薦得分最高的5個(gè)標(biāo)簽時(shí), Recall@5為56.3%, 即超過50%的標(biāo)簽都推薦正確; 而推薦得分最高的10個(gè)標(biāo)簽時(shí), 正確率提高了10%. 本文方法在3項(xiàng)指標(biāo)上都高于文獻(xiàn)[6]方法, 在Recall@5和Recall@10指標(biāo)上接近文獻(xiàn)[2]方法, 且在更精細(xì)的Recall@3指標(biāo)上本文方法性能更好.
對(duì)推薦錯(cuò)誤的標(biāo)簽進(jìn)行分析, 主要原因有: 某些包的Readme文檔描述文本過少, 不能從中抽取到足夠的信息, 也無法通過詞頻顯現(xiàn)出描述文本的主題, 從而導(dǎo)致本文方法無法準(zhǔn)確地構(gòu)建包與標(biāo)簽之間的聯(lián)系, 最后導(dǎo)致分析結(jié)果錯(cuò)誤. 由于文獻(xiàn)[2]方法不僅利用了Readme文檔而且利用了文件名、 wiki等文本進(jìn)行數(shù)據(jù)挖掘訓(xùn)練, 所以在推薦數(shù)量較多標(biāo)簽時(shí)效果略優(yōu)于本文方法, 但當(dāng)推薦標(biāo)簽數(shù)量較少時(shí), 本文方法準(zhǔn)確率更高.
綜上所述, 本文提出了一種為npm包推薦標(biāo)簽的方法, 通過解決現(xiàn)有標(biāo)簽同義詞的問題建立標(biāo)簽庫(kù), 并基于詞向量挖掘包的描述文本與標(biāo)簽之間的語義關(guān)系實(shí)現(xiàn)標(biāo)簽推薦. 實(shí)驗(yàn)結(jié)果表明, 該方法能有效完成推薦標(biāo)簽的工作.