楊立月 王移芝
(北京交通大學(xué)計(jì)算機(jī)與信息技術(shù)學(xué)院 北京 100044)
近年來(lái)隨著互聯(lián)網(wǎng)的發(fā)展,文本情感分析成為一個(gè)新興的課題,并體現(xiàn)出了非常廣闊的應(yīng)用價(jià)值。比如,根據(jù)微博的文本情感分析可以監(jiān)測(cè)輿論傾向、預(yù)測(cè)股票漲跌、預(yù)測(cè)電影票房等[1];根據(jù)對(duì)商品評(píng)論信息的文本情感分析可以得到用戶對(duì)于商品的喜愛(ài)程度、發(fā)掘商品供求和推銷信息等[2]。由于中文語(yǔ)義的復(fù)雜性和強(qiáng)順序性,機(jī)器學(xué)習(xí)中的單一分類器往往不能取得非常好的分類效果[3]。近幾年來(lái),利用集成學(xué)習(xí)的方法進(jìn)行綜合的文本情感分類,取得了非常好的效果[4]。但集成學(xué)習(xí)由傳統(tǒng)的單個(gè)分類器改為多分類器集成,造成了計(jì)算量的成倍增長(zhǎng)[5],隨著微博和微信等社交工具的流行,文本信息數(shù)量呈現(xiàn)爆炸性的增長(zhǎng),單機(jī)環(huán)境已經(jīng)不能滿足集成學(xué)習(xí)的算力要求,集成學(xué)習(xí)的時(shí)間成本已經(jīng)成為大規(guī)模文本情感分析的一個(gè)痛點(diǎn)。
近幾年,以Spark和MapReduce為代表的大數(shù)據(jù)分析技術(shù)的發(fā)展,為解決集成學(xué)習(xí)中單點(diǎn)算力的痛點(diǎn)帶來(lái)了曙光[6]。集成學(xué)習(xí)過(guò)程中,在模型結(jié)果進(jìn)行集成算法前單個(gè)模型的相對(duì)獨(dú)立性能夠盡可能地減少網(wǎng)絡(luò)通信和shuffle過(guò)程,充分發(fā)揮分布式計(jì)算框架的性能,非常契合Spark這種分布式計(jì)算框架。本文使用Spark集群,利用其編程模型中的parallel算子將集成學(xué)習(xí)中的分類任務(wù)進(jìn)行模型分離,并利用Yarn調(diào)度器進(jìn)行任務(wù)均衡分發(fā)和監(jiān)控,最后將各模型的結(jié)果收集回driver端進(jìn)行集成得到最終結(jié)果。實(shí)驗(yàn)證明該算法具有良好的拓展性和加速比,很好地解決了大規(guī)模集成學(xué)習(xí)中單機(jī)實(shí)驗(yàn)的時(shí)間瓶頸問(wèn)題,大幅度降低了使用集成學(xué)習(xí)進(jìn)行大規(guī)模文本情感分析的時(shí)間成本。
文本情感分析是自然語(yǔ)言處理中一個(gè)非常重要和實(shí)用方法。目前針對(duì)文本的情感傾向分析方法主要有兩種:基于情感詞典的方法和基于機(jī)器學(xué)習(xí)的方法。兩種方法各有優(yōu)劣,情感詞典的方法主要優(yōu)點(diǎn)是穩(wěn)定,常常根據(jù)情感詞就可以推斷出整個(gè)文本的情感傾向,缺點(diǎn)是對(duì)于不在情感詞典中的詞無(wú)能為力,而且無(wú)法結(jié)合語(yǔ)義上下文的語(yǔ)境,而同一個(gè)詞在不同語(yǔ)境中可能完全表達(dá)相反的含義[7]。機(jī)器學(xué)習(xí)方法常常需要人工標(biāo)注語(yǔ)料作為訓(xùn)練集,提取出文本的特征,用特征構(gòu)建一個(gè)分類器,再做情感的分類。但是這種方法因?yàn)闄C(jī)器學(xué)習(xí)中單個(gè)模型特征的抽取方法不同,通用性不好,而且抽取過(guò)程中受訓(xùn)練語(yǔ)料噪音的影響進(jìn)而導(dǎo)致分類效果并不太理想[8]。
集成學(xué)習(xí)是近幾年興起的一種新型的機(jī)器學(xué)習(xí)方式,通過(guò)構(gòu)建并結(jié)合多個(gè)學(xué)習(xí)器來(lái)完成學(xué)習(xí)任務(wù),在集成學(xué)習(xí)中通過(guò)各個(gè)學(xué)習(xí)器進(jìn)行結(jié)合,可以獲得比單一學(xué)習(xí)器更優(yōu)越的泛化性能。通常情況下,有監(jiān)督的學(xué)習(xí)方法都是針對(duì)一個(gè)問(wèn)題從一個(gè)有限的假設(shè)空間中搜索最適合結(jié)果。而集成學(xué)習(xí)就是將多個(gè)假設(shè)空間放到一起來(lái)形成一個(gè)更好的方案。集成學(xué)習(xí)的結(jié)果是一個(gè)單一的假設(shè)空間,不一定是在原始分類器的假設(shè)空間中,因此具有更高的靈活性[9]。理論上說(shuō),集成學(xué)習(xí)可以在訓(xùn)練集上比單一的模型有更好的擬合能力,如bagging等集成學(xué)習(xí)方法在實(shí)際中能更好地降低過(guò)擬合的問(wèn)題??偠灾?,集成學(xué)習(xí)能夠集百家之長(zhǎng),擁有更高更穩(wěn)定的分類準(zhǔn)確性,是文本情感傾向分析中的一個(gè)重要方向。但集成學(xué)習(xí)由于需要計(jì)算多個(gè)模型的數(shù)據(jù)結(jié)果,因此通常意味著計(jì)算量的成倍增加,而且伴隨模型調(diào)參和集成方法測(cè)試等優(yōu)化方法的使用更進(jìn)一步放大了該問(wèn)題,大規(guī)模集成學(xué)習(xí)文本情感分析的時(shí)間成本成為一個(gè)痛點(diǎn)。
Spark是一個(gè)Apache開(kāi)源的分布式計(jì)算框架,具有速度快且通用性好的特點(diǎn)。其原本是UC Berkeley的AMP實(shí)驗(yàn)室開(kāi)發(fā)的一個(gè)類似于谷歌的MapReduce的并行框架[10],但不同于MapReduce,Apache Spark計(jì)算的中間結(jié)果可以優(yōu)先保存在內(nèi)存中,從而不再需要頻繁地讀寫硬盤,因此能夠獲得更快的大數(shù)據(jù)處理速度[11]。圖1展示了Spark的基本框架,用戶首先通過(guò)spark-submit命令向集群提交作業(yè),然后Driver向Master注冊(cè)本次作業(yè)并且向集群申請(qǐng)資源。由于Master與各個(gè)worker之間有心跳包報(bào)告機(jī)器資源狀況,因此Master能夠找到最合適的機(jī)器資源給本任務(wù),再在各個(gè)有資源的節(jié)點(diǎn)上啟動(dòng)Executor進(jìn)程去運(yùn)行用戶提交任務(wù)中的每一個(gè)task,Executor向Driver通過(guò)心跳包報(bào)告運(yùn)行狀態(tài),直到作業(yè)完成。像Spark這種分布式計(jì)算框架的瓶頸往往在于網(wǎng)絡(luò)IO,而集成學(xué)習(xí)中在模型切分后單個(gè)模型之間是相對(duì)獨(dú)立的,不需要與其他的節(jié)點(diǎn)通過(guò)網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交互,因此能夠充分發(fā)揮集群機(jī)器的計(jì)算性能。
圖1 Spark框架的工作流程
集成學(xué)習(xí)模型并行算法分為模型切分與任務(wù)分發(fā)、文本數(shù)據(jù)處理與預(yù)測(cè)、預(yù)測(cè)結(jié)果拉回和模型集成四個(gè)階段。首先利用Spark中的parallel算子生成與模型個(gè)數(shù)相匹配的簡(jiǎn)單分布式數(shù)據(jù)集RDD,然后通過(guò)對(duì)該RDD的MapPartition操作將各個(gè)模型進(jìn)行均勻分發(fā)。在該操作內(nèi)部進(jìn)行模型的加載并且讀取HDFS中的文本數(shù)據(jù),進(jìn)行文本處理和當(dāng)前模型的結(jié)果預(yù)測(cè),將預(yù)測(cè)結(jié)果通過(guò)Itertor迭代器的形式返回[12]。最后執(zhí)行collect算子操作,將所有預(yù)測(cè)的數(shù)據(jù)拉回driver端,然后根據(jù)各個(gè)模型的結(jié)果使用集成算法進(jìn)行集成,并將最后的預(yù)測(cè)結(jié)果和評(píng)價(jià)數(shù)據(jù)寫入HDFS中。圖2展示了利用Spark平臺(tái)進(jìn)行大規(guī)模集成學(xué)習(xí)分析文本情感的作業(yè)流程。
圖2 Spark中集成學(xué)習(xí)文本分析流程
并行算法的工程化主要是使用scala語(yǔ)言,按照Spark中RDD的編程模型,主要使用的算子包括mapPartition、parallel、collect等,具體偽代碼如算法1所示。
算法1Spark集成學(xué)習(xí)文本情感分析算法
輸入:文本數(shù)據(jù),模型,節(jié)點(diǎn)配置
輸出:集成學(xué)習(xí)分類結(jié)果與評(píng)價(jià)指標(biāo)
1. val context=SparkContext()
2. val textConfig=context.getConf.get()
3. val modelNum=context.getConf.get()
4. val dataPath=context.getConf.get()
5. val classify=context.parallelize(0 until modelNum,modelNum).mapPartitions {part=>
data=HDFS.read(dataPath)
model=HDFS.read(model)
singelResult=model.fit(data)
singelResult.iterator()
}
6. val result=classify.collect()
7. val ensembleResult=result.ensemble()
8. save ensembleResult and evaluate
本實(shí)驗(yàn)所用的機(jī)器為購(gòu)買的4臺(tái)阿里云的CES服務(wù)器,在線安裝配置了Spark和HDFS環(huán)境。為了方便進(jìn)行對(duì)比實(shí)驗(yàn),單機(jī)數(shù)據(jù)采用的機(jī)器環(huán)境和Spark集群中單個(gè)節(jié)點(diǎn)的機(jī)器配置完全相同。表1給出了Spark集群中單個(gè)節(jié)點(diǎn)的主要硬件配置,表2給出了單節(jié)點(diǎn)主要的軟件環(huán)境及對(duì)應(yīng)的版本號(hào)。
表1 Spark集群?jiǎn)喂?jié)點(diǎn)硬件配置信息
表2 Spark集群?jiǎn)喂?jié)點(diǎn)軟件配置信息
實(shí)驗(yàn)選擇標(biāo)準(zhǔn)的SVM、CRF和LR模型進(jìn)行文本情感傾向分類的普通投票法集成學(xué)習(xí)分類。為了檢驗(yàn)上述的指標(biāo),實(shí)驗(yàn)分別選擇了單機(jī)、2節(jié)點(diǎn)、3節(jié)點(diǎn)、4節(jié)點(diǎn)共四組進(jìn)行橫向?qū)Ρ?;選擇了100萬(wàn)、200萬(wàn)和400萬(wàn)條三個(gè)不同數(shù)量的微博文本進(jìn)行縱向?qū)Ρ?。主要選取程序運(yùn)行時(shí)間、集成學(xué)習(xí)的F-score、加速比和可拓展性作為本次實(shí)驗(yàn)的主要評(píng)價(jià)指標(biāo)。各評(píng)價(jià)指標(biāo)說(shuō)明如下:
(1) 運(yùn)行時(shí)間(Runtime):該指標(biāo)是本次實(shí)驗(yàn)最主要的目的指標(biāo),具體的運(yùn)行時(shí)間計(jì)算是從提交作業(yè)成功開(kāi)始到模型集成學(xué)習(xí)完畢所需的總時(shí)間。
(2) F-score:由于在分類實(shí)驗(yàn)中的準(zhǔn)確率P和召回率R有時(shí)候會(huì)出現(xiàn)互相矛盾的情況,這樣就需要綜合考慮兩者,最常見(jiàn)的方法就是F-score,其與準(zhǔn)確率P和召回率R的關(guān)系如下:
當(dāng)參數(shù)α=1時(shí),就是最常見(jiàn)的F1指標(biāo),即:
本文計(jì)算的F-score選用F1指標(biāo)。
(3) 加速比(Speedup):該指標(biāo)是基本運(yùn)行時(shí)間與并行時(shí)間的比值,主要是用于驗(yàn)證并行算法的效率,根據(jù)Amdahl定律,集群的加速比在理想的狀態(tài)下一般被定義為:
(4) 可拓展性(Extension):該指標(biāo)主要能夠反映出集群機(jī)器數(shù)目的改變對(duì)該算法的主要性能影響的大小,一般通過(guò)這項(xiàng)指標(biāo)可以預(yù)判集群機(jī)器數(shù)目與該算法的效率匹配性。
實(shí)驗(yàn)1本次實(shí)驗(yàn)對(duì)比了集成學(xué)習(xí)的運(yùn)行時(shí)間隨著集群的節(jié)點(diǎn)數(shù)N的變化。實(shí)驗(yàn)數(shù)據(jù)如表3所示。
表3 運(yùn)行時(shí)間實(shí)驗(yàn)結(jié)果
通過(guò)橫向?qū)Ρ瓤梢园l(fā)現(xiàn),集成學(xué)習(xí)的時(shí)間隨著集群節(jié)點(diǎn)數(shù)的增加而明顯下降,且基本呈現(xiàn)線性關(guān)系。通過(guò)縱向?qū)Ρ瓤梢园l(fā)現(xiàn),集成學(xué)習(xí)的時(shí)間隨著樣本數(shù)目的增加而大幅增加,且基本呈現(xiàn)倍數(shù)關(guān)系,實(shí)驗(yàn)數(shù)據(jù)基本符合先驗(yàn)預(yù)期。
實(shí)驗(yàn)2該實(shí)驗(yàn)是評(píng)價(jià)分類模型優(yōu)劣的標(biāo)準(zhǔn)之一,通過(guò)計(jì)算F-score的方式綜合考慮分類任務(wù)的準(zhǔn)確率和召回率。實(shí)驗(yàn)數(shù)據(jù)如表4所示,可以看出,無(wú)論從橫向的節(jié)點(diǎn)數(shù)目來(lái)看還是從縱向的分類樣本數(shù)目來(lái)看,文本情感分類的F-score基本保持比較穩(wěn)定的狀態(tài),且樣本數(shù)量越大穩(wěn)定性越好,這與單機(jī)實(shí)驗(yàn)的相關(guān)指標(biāo)基本一致。
表4 F-score實(shí)驗(yàn)結(jié)果
實(shí)驗(yàn)3在集群不同節(jié)點(diǎn)數(shù)下的加速比折線圖如圖3所示。
圖3 加速比示意圖
可以看出,利用Spark平臺(tái)進(jìn)行分布式集成學(xué)習(xí)文本情感分類,加速比隨著集群規(guī)模而成倍增加,但是隨著文本數(shù)量的持續(xù)增加,加速比曲線的上升速度有了一定程度的下降。這是因?yàn)楫?dāng)數(shù)據(jù)量增加后,集群中單節(jié)點(diǎn)需要處理的數(shù)據(jù)也隨之增加,由于Spark平臺(tái)使用的Scala語(yǔ)言是運(yùn)行在Java虛擬機(jī)上的語(yǔ)言[13],因此更多的數(shù)據(jù)量就會(huì)觸發(fā)更多次的GC(垃圾回收),從而使加速比上升速度出現(xiàn)一定的下降。
實(shí)驗(yàn)4將運(yùn)行時(shí)間隨節(jié)點(diǎn)數(shù)的變化作折線圖如圖4所示。
圖4 擴(kuò)展性示意圖
可以看出,使用集成學(xué)習(xí)方法在三個(gè)不同數(shù)量的文本樣本進(jìn)行情感傾向分類,運(yùn)行時(shí)間基本隨著集群節(jié)點(diǎn)數(shù)的上升而下降,基本呈現(xiàn)線性關(guān)系。結(jié)果說(shuō)明,該集成學(xué)習(xí)的并行算法有著非常良好的拓展性,可以推測(cè)該算法在更大規(guī)模的集群上也能有非常好的表現(xiàn)。
隨著微博、微信等社交工具的流行,傳統(tǒng)利用Python等語(yǔ)言進(jìn)行單機(jī)集成學(xué)習(xí)的算法在面對(duì)指數(shù)級(jí)增長(zhǎng)的文本數(shù)量時(shí),完成一次大規(guī)模的文本情感分析往往需要非常巨大的時(shí)間成本,嚴(yán)重影響了文本分類實(shí)驗(yàn)的效率。Spark這種分布式計(jì)算框架為集成學(xué)習(xí)中模型的并行化提供了非常簡(jiǎn)單有效的方法,大大縮短了單次實(shí)驗(yàn)的時(shí)間,提高了模型優(yōu)化和調(diào)參的效率。實(shí)驗(yàn)表明,利用Spark平臺(tái)進(jìn)行集成學(xué)習(xí)中模型的并行化可以基本線性地縮短文本分類時(shí)間,分類F-score等指標(biāo)與單機(jī)算法基本相同,且并行算法的可拓展性良好,能夠在可預(yù)見(jiàn)的情況下支撐更大規(guī)模的文本情感分類。