文本相似性的應(yīng)用場(chǎng)景會(huì)有很多短纵,在工業(yè)界我粗略遇到過:
- 熱點(diǎn)做輿情識(shí)別監(jiān)控的時(shí)候,需要對(duì)全網(wǎng)文章進(jìn)行聚合,聚合過程中需要知道哪些文章是一致的
- 推薦做相似內(nèi)容召回的時(shí)候亿扁,需要對(duì)文章內(nèi)容進(jìn)行匹配,匹配過程中需要知道哪些文章是一致的
- 特殊分類場(chǎng)景浅碾,比如fake news這種樣本集合較小的場(chǎng)景下大州,相似匹配可以用來補(bǔ)充分類結(jié)果
- ...
說到文本相似性可以有很多種劃分的方式,從文章的長(zhǎng)短可以分別處理垂谢,從計(jì)算的方式可以分為深度學(xué)習(xí)和機(jī)器學(xué)習(xí)方式厦画,從實(shí)現(xiàn)目的上可以分為去重和匹配...
以下面兩個(gè)例子舉例:
0 偉大祖國(guó)讓我們過的非常幸福
1 偉大的祖國(guó)讓我們過的非常幸福
2 偉大的祖國(guó)是我們過的非常幸福原因
3 中國(guó)人民現(xiàn)在的日子真的很幸福
Hash方法
我們可以說0和1是相似的,因?yàn)樗鼈冎g只差了一個(gè)“的”滥朱,通常通過SimiHash或者M(jìn)iniHash我們就可以解決這類問題
分詞根暑、hash、加權(quán)徙邻、合并排嫌、降維,這個(gè)是它們?cè)诔R?guī)流程缰犁〈镜兀總結(jié)一下就是,根據(jù)各種權(quán)重賦值方式(比如tfidf)給出每個(gè)詞的權(quán)重帅容,通過hash的方式給每個(gè)詞一個(gè)01表征方式颇象,通過權(quán)重和表征結(jié)果得到加權(quán)結(jié)果,再根據(jù)加權(quán)結(jié)果map到0或者1并徘,得到一串簽名結(jié)果Fingerprints遣钳,再通過分段比對(duì)或者其他什么方式進(jìn)行兩句話的比對(duì),看下差異是否在可接受的范圍內(nèi)麦乞,得到兩句話是否一致蕴茴。
這種方式通常用作去重,比如如果我們有一份非常龐大的樣本集合路幸,要去做去重荐开,大家通常的做法就是在寫hive sql或者spark sql的時(shí)候distinct一下,在做后續(xù)的自然語(yǔ)言處理任務(wù)简肴,通過這種方式可以去除掉一些真·近似的文本晃听,加快速度且干掉一些異常點(diǎn)非常有效,最重要的是超級(jí)快砰识。
詞袋方法
1和2由于相差的字?jǐn)?shù)比較多能扒,可能不是以一種hash方式去做能識(shí)別多出的。但是細(xì)心的朋友回發(fā)現(xiàn)辫狼,它們之間重合率非常高初斑,通過分詞后的比對(duì)也是可以識(shí)別的。
這邊點(diǎn)名一下常見的倒排索引膨处、杰卡德相似见秤、onehot的cosine砂竖、切詞后的詞交集個(gè)數(shù),句法依存鹃答,編輯距離等等乎澄,都可以實(shí)現(xiàn),而且其中不乏一些非常高效的解決方案测摔,相似框架faiss置济,l2正則化后稀疏矩陣點(diǎn)積,tire樹做文本內(nèi)容的存儲(chǔ)以匹配詞交叉的情況等等锋八。
這種方式通常是應(yīng)用在業(yè)務(wù)場(chǎng)景中了浙于,它們通常不會(huì)作為一個(gè)自然語(yǔ)言理解必備的preprocessing工作去做,而是解決一系列要求高時(shí)效或者要求高相似的文本判斷的場(chǎng)景下挟纱。
匹配方法
剛才為說到要求高相似羞酗,很多朋友可能不理解什么叫做高相似,對(duì)比1和2樊销,2和3就會(huì)發(fā)現(xiàn)整慎,大家對(duì)相似的標(biāo)準(zhǔn)其實(shí)是不一致的脏款,在某些場(chǎng)景围苫,比如熱點(diǎn)榜單生成,1撤师,2剂府,3就是一件事情,大家都不喜歡在自己的熱榜排序結(jié)果中重復(fù)出現(xiàn)1剃盾,2腺占,3中的任意2條;而在信息流推薦中痒谴,2衰伯,3或者,1积蔚,3就是兩件不同的事情意鲸,可能它們的文章有不同的側(cè)重點(diǎn)。
如果需要識(shí)別出1尽爆,2怎顾,3是同一件事情,可能詞袋方法也不適用漱贱,因?yàn)樗鼈儧]啥重復(fù)的詞槐雾,詞袋就失效了。
- LDA
- TWE
- WordEmbedding
- SentenceEmbedding
- BERT
- supervised method
以上6種方式是工業(yè)界最常用的6種思路幅狮,不乏會(huì)有一些奇思妙想沒有列出來募强,但是各大廠主力的方法一定包含在其上株灸。
LDA
LDA是一個(gè)nlp工程師必會(huì)的技能,這邊不展開講擎值,這邊主要講它能帶來什么蚂且。LDA這個(gè)方法對(duì)一段文本的表征,它優(yōu)秀在于考慮了當(dāng)前文本和全局之間的關(guān)系幅恋,我在做文本匹配的時(shí)候杏死,我不簡(jiǎn)簡(jiǎn)單單的立足在這個(gè)兩篇文本是否一致,而是把它放在了全部數(shù)據(jù)集中捆交,拼的是文本1淑翼、文本2在全量數(shù)據(jù)集中到底是個(gè)什么地位,在全部的文檔庫(kù)中這兩個(gè)文本講的到底是不是一類事情品追。
LDA提供的是兩篇文本的主題的分布玄括,得到這個(gè)量化后的分布后如何去比呢?cosine肉瓦?其實(shí)大家在高代學(xué)習(xí)過程中一定聽過相對(duì)熵這個(gè)邏輯遭京,從這個(gè)角度上來看,是不是text1對(duì)text2的相對(duì)熵和text2對(duì)text1的相對(duì)熵的加權(quán)平均很合適泞莉,因?yàn)樗鼈兌际呛饬康膬蓚€(gè)分布上的一致性哪雕,而主題恰巧是text本文的分布。對(duì)鲫趁,這個(gè)方法就是JS散度斯嚎。另外一種方式是Hellinger Distance,它的中文名叫概率分布之間的距離--海林格距離挨厚,話不多說堡僻,同理易得。
這邊補(bǔ)充一下疫剃,百度的Familia就集成這兩種方式去算相似度钉疫,異常好用。
TWE
用過LDA的人應(yīng)該知道:LDA 產(chǎn)生的主題往往被高頻詞占據(jù)巢价,這種現(xiàn)象導(dǎo)致低頻詞在實(shí)際應(yīng)用中的作用非常有限牲阁。
知道LDA原理的人應(yīng)該知道:LDA通常假設(shè)同一個(gè)句子里的詞產(chǎn)生自同一主題,對(duì)句子內(nèi)的詞進(jìn)行了進(jìn)一步的建模蹄溉。
顯而易見咨油,這些都是不合理的。
Topical Word Embedding (TWE) 利用 LDA 訓(xùn)練獲得的主題為詞向量的訓(xùn)練提供補(bǔ)充信息柒爵,進(jìn)而得到詞和主題的向量表示役电。也就是說,我得到了主題向量棉胀,我也得到詞向量法瑟,我結(jié)合兩者一起來補(bǔ)充信息冀膝,這樣我既照顧到了句的主題,也沒有損失詞的多樣性信息霎挟。
如何去生成:
- 我們將每個(gè)主題視為一個(gè)偽詞(pseudo word)窝剖,分別學(xué)習(xí)主題向量和詞向量。然后根據(jù)向量wiwi和zizi構(gòu)建主題詞向量?wi,zi??wi,zi?
- 我們將每個(gè)單詞詞-主題對(duì)?wi,zi??wi,zi?視為一個(gè)偽詞(pseudo word)酥夭,并直接學(xué)習(xí)到主題詞向量
- 我們分別為每個(gè)詞和每個(gè)主題保留不同的嵌入向量赐纱,通過連接相應(yīng)的單詞和主題向量來建立每個(gè)單詞-主題對(duì)的向量
法1精度差但是好實(shí)現(xiàn),法2訓(xùn)練時(shí)間長(zhǎng)但是效果更可接受熬北,法3給單詞embedded學(xué)習(xí)過程中引入了主題向量的影響疙描。我現(xiàn)在一般用3,但是我覺得2是也是可接受的讶隐。
WordEmbedding
這段比較無腦起胰,是個(gè)nlp工程師都用過的方式。GloVe巫延,F(xiàn)astText效五,W2V,DSSM生成詞的向量化表征結(jié)果炉峰,然后通過SIF畏妖,加權(quán),Attention讲冠,平均瓜客,求和适瓦,Pooling等各種花里胡哨的方法然后在計(jì)算Cosine相似度竿开。
這個(gè)方法一定是baseline,效果非巢N酰可觀否彩,這邊不多說。只是給大家分享一些我使用的心得
- 找個(gè)靠譜的詞向量做Fine-tune嗦随,不要隨機(jī)列荔。這邊我是用的集團(tuán)AI提供的詞向量,開源的有騰訊16G枚尼,搜狗的20G贴浙,科大訊飛的8G結(jié)果
- 數(shù)據(jù)越多,越好署恍。但是要的是分布均勻的數(shù)據(jù)崎溃,玩命懟一個(gè)方向的數(shù)據(jù)對(duì)提升效果作用=0,我在finetune的時(shí)候是打散后的38個(gè)垂類的1億2000萬(wàn)條資訊文章盯质,而且這些文章已經(jīng)做了fingerprint過濾的
- 不要剔除過多的詞袁串,不要只保留實(shí)體概而。一些連接詞的學(xué)習(xí)會(huì)帶來句子的連慣性上的幫助。假如你有一天需要做seq2seq的任務(wù)呢囱修?
- 添加<CLS>可以幫你索定詞位置赎瑰,引入可以幫助你解決一些語(yǔ)句合理性判斷的問題
- 把過短的內(nèi)容刪掉,1個(gè)字的詞刪掉破镰,純數(shù)字刪掉餐曼,如果是資訊文章最后的版權(quán)聲明刪掉,小細(xì)節(jié)注意一下
word embedding會(huì)帶來一種問題鲜漩,蘋果和香蕉相關(guān)晋辆,“我下午想吃香蕉”和“我下午想吃蘋果”,word embedding認(rèn)為是一件事宇整,但是實(shí)際可能并不是瓶佳。
SentenceEmbedding
Sentence Embedding認(rèn)為既然一個(gè)詞可以是一個(gè)向量,一句話也可以是鳞青。這邊的論文一堆霸饲,方法也一堆:doc2vec,Infersent臂拓,Sentence2Vec厚脉,skip-thought,Quick-Thought胶惰,F(xiàn)astSent傻工。
以上這些是我看過還沒忘的,我覺得比較有價(jià)值的孵滞。它們基于不同的思想中捆,也有不同的作用,我這邊談幾個(gè)比較經(jīng)典的坊饶。
- doc2vec是word2vec翻版泄伪,通常的做法是在句首加一個(gè)<CLS>,學(xué)習(xí)到的<CLS>的向量作為句向量匿级。
- Skip-thought利用中心句預(yù)測(cè)context中的句子蟋滴,用了一個(gè)encoder來壓縮中心句子的信息,然后用兩個(gè)decoder來產(chǎn)生context里的句子痘绎,一個(gè)decoder用于預(yù)測(cè)前一句津函,另外一個(gè)decoder用于預(yù)測(cè)后一句。
QT針對(duì)這個(gè)問題孤页,對(duì)decoder部分做了大的調(diào)整尔苦,它直接把decoder拿掉,取而代之的是一個(gè)classifier,使得預(yù)測(cè)行為變成了分類行為蕉堰。就是用向量點(diǎn)積來判斷同樣的encoder的向量的相似度凌净。 - Sentence2Vec是Skip-thought加強(qiáng)版
- Infersent是有監(jiān)督的方法,用的是相似內(nèi)容對(duì)屋讶,構(gòu)造了<u冰寻,v,|u-v|,u*v>進(jìn)行Entailment、contradiction and neutral三分類的預(yù)測(cè)
- FastSent皿渗,用上下文的詞來預(yù)測(cè)目標(biāo)句子的詞斩芭,然后把目標(biāo)句的詞的和作為目標(biāo)句的向量
句向量來補(bǔ)充詞向量衡量一個(gè)句子的相似度會(huì)有明顯的提升,我日常做baseline就是wordembedding+sentenceembedding來算cosine的
Bert
原理就不講了乐疆,一萬(wàn)個(gè)人寫過bolg了划乖,這邊給大家整理了一份易錯(cuò)知識(shí)點(diǎn)Bert知識(shí)點(diǎn)。
主要注意的是:
- 原始的bertbase別用挤土,效果差琴庵,建議在自己的數(shù)據(jù)集上微調(diào)
- 不要用CLS或者詞向量拼接的方式,建議拿倒數(shù)第一層的output向量仰美,你需要的只是句子綜合信息
- 這個(gè)速度真的慢迷殿,考慮場(chǎng)景,收益沒有想的那么大
supervised method
有監(jiān)督的方式大概有兩種思路:
- fasttext/infersent這種用有監(jiān)督的方式生成詞向量或者句向量方式咖杂,再計(jì)算句詞向量之間的cosine相似度
- 直接求解(Universal Sentence Encoder/DSSM)
- 第一步選擇監(jiān)督訓(xùn)練數(shù)據(jù)庆寺,設(shè)計(jì)相應(yīng)的包含句子編碼器Encoder的模型框架
- 第二步選擇(設(shè)計(jì))具體的句子編碼器,包括DAN诉字、基于LSTM懦尝、基于CNN和Transformer等
正兒八經(jīng)的人用infersent或者fasttext這種就行了,越復(fù)雜的設(shè)計(jì)帶來的風(fēng)險(xiǎn)在工業(yè)界也是難以hold住的壤圃。
以上這些陵霉,匹配方法可以得到2和3這種語(yǔ)句的聚合,但是需要考慮使用場(chǎng)景和收益率埃唯。
總結(jié)
講道理撩匕,上面這些方法可以覆蓋日常工作中的絕大多數(shù)文本相似度計(jì)算的方法,剩下就是如何去融合成一個(gè)適合場(chǎng)景的解決方案了墨叛。代碼按大家的需要后續(xù)給大家開源。