主題與轉(zhuǎn)換(Topics and Transformations)

如果想要開啟日志衷佃,別忘記設(shè)置:

>>>importlogging>>>logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

1

2

轉(zhuǎn)換接口

在之前的教程《語料庫與向量空間》中芥颈,我們創(chuàng)建了一個(gè)用向量流表示文檔的語料庫呀洲。為了繼續(xù)征程豫喧,讓我們啟動(dòng)gensim并使用該語料庫幕垦。

>>>fromgensimimportcorpora, models, similarities>>>dictionary = corpora.Dictionary.load('/tmp/deerwester.dict')>>>corpus = corpora.MmCorpus('/tmp/deerwester.mm')>>>print(corpus)MmCorpus(9documents,12features,28non-zero entries)

1

2

3

4

5

在本次教程中吼具,我將會(huì)向你展示如何將文檔從一種向量表示方式轉(zhuǎn)換到另一種赡勘。這個(gè)處理是為了兩個(gè)目的:

將語料庫中隱藏的結(jié)構(gòu)發(fā)掘出來,發(fā)現(xiàn)詞語之間的關(guān)系楼熄,并且利用這些結(jié)構(gòu)忆绰、關(guān)系使用一種新的、更有語義價(jià)值的(這是我們最希望的)方式描述其中的文檔可岂。

使得表示方式更加簡潔错敢。這樣不僅能提高效率(新的表示方法一般消耗較少的資源)還能提高效果(忽略了邊際數(shù)據(jù)趨勢、降低了噪音)青柄。

創(chuàng)建一個(gè)轉(zhuǎn)換

轉(zhuǎn)換(transformations)是標(biāo)準(zhǔn)的Python類伐债,通常通過訓(xùn)練語料庫的方式初始化

>>>tfidf = models.TfidfModel(corpus)# 第一步 -- 初始化一個(gè)模型

1

我們使用了前一個(gè)教程中用過的語料庫來初始化(訓(xùn)練)這個(gè)轉(zhuǎn)換模型。不同的轉(zhuǎn)換可能需要不同的初始化參數(shù)致开;在Tfidf案例中峰锁,“訓(xùn)練”僅僅是遍歷提供的語料庫然后計(jì)算所有屬性的文檔頻率(譯者注:在多少文檔中過)。訓(xùn)練其他模型双戳,例如潛在語義分析或隱含狄利克雷分配虹蒋,更加復(fù)雜,因此耗時(shí)也多飒货。

作者注:轉(zhuǎn)換常常是在兩個(gè)特定的向量空間之間進(jìn)行魄衅。訓(xùn)練與后續(xù)的轉(zhuǎn)換必須使用相同的向量空間(=有相同的屬性,且編號(hào)相同)塘辅。如若不然晃虫,例如使用不同的預(yù)處理方法處理字符串、使用不同的屬性編號(hào)扣墩、需要Tfidf向量的時(shí)候卻輸入了詞袋向量哲银,將會(huì)導(dǎo)致轉(zhuǎn)換過程中屬性匹配錯(cuò)誤,進(jìn)而使輸出結(jié)果無意義并可能引發(fā)異常呻惕。

轉(zhuǎn)換向量

從現(xiàn)在開始荆责,tfidf將被視為只讀的對象,可以用它來轉(zhuǎn)換將任何采用舊表示方法的向量(詞袋整數(shù)計(jì)數(shù))轉(zhuǎn)換為新的表示方法(Tfidf 實(shí)數(shù)權(quán)重):

>>>doc_bow = [(0,1), (1,1)]>>>print(tfidf[doc_bow])# 第二步 -- 使用模型轉(zhuǎn)換向量[(0,0.70710678), (1,0.70710678)]

1

2

3

或者對整個(gè)語料庫實(shí)施轉(zhuǎn)換:

>>>corpus_tfidf = tfidf[corpus]>>>fordocincorpus_tfidf:...print(doc)[(0,0.57735026918962573), (1,0.57735026918962573), (2,0.57735026918962573)][(0,0.44424552527467476), (3,0.44424552527467476), (4,0.44424552527467476), (5,0.32448702061385548), (6,0.44424552527467476), (7,0.32448702061385548)][(2,0.5710059809418182), (5,0.41707573620227772), (7,0.41707573620227772), (8,0.5710059809418182)][(1,0.49182558987264147), (5,0.71848116070837686), (8,0.49182558987264147)][(3,0.62825804686700459), (6,0.62825804686700459), (7,0.45889394536615247)][(9,1.0)][(9,0.70710678118654746), (10,0.70710678118654746)][(9,0.50804290089167492), (10,0.50804290089167492), (11,0.69554641952003704)][(4,0.62825804686700459), (10,0.45889394536615247), (11,0.62825804686700459)]

1

2

3

4

5

6

7

8

9

10

11

12

在這個(gè)特殊的情況中亚脆,被轉(zhuǎn)換的語料庫與用來訓(xùn)練的語料庫相同做院,但是這僅僅是偶然。一旦轉(zhuǎn)換模型被初始化了濒持,它可以用來轉(zhuǎn)換任何向量(當(dāng)然最好使用與訓(xùn)練語料庫相同的向量空間 | 注:即語言環(huán)境)键耕,即使它們并沒有在訓(xùn)練語料庫中出現(xiàn)。這是通過潛在語義分析的調(diào)入(folding in)弥喉、隱含狄利克雷分配的主題推斷(topic inference)等得到的郁竟。

調(diào)用model[corpus]只能在舊的corpus文檔流的基礎(chǔ)上創(chuàng)建一個(gè)包裝-真正的轉(zhuǎn)化是在迭代文檔時(shí)即時(shí)計(jì)算的。我們可以通過調(diào)用corpus_transformed = model[corpus]一次轉(zhuǎn)化整個(gè)語料庫由境,因?yàn)檫@樣意味著我們要將結(jié)果存入內(nèi)存中棚亩,這與gensim內(nèi)存無關(guān)的設(shè)計(jì)理念不太符合。如果你還要多次迭代轉(zhuǎn)化后的corpus_transformed虏杰,負(fù)擔(dān)將會(huì)十分巨大讥蟆。你可以先將結(jié)果序列化并存儲(chǔ)到硬盤上再做需要的操作。

轉(zhuǎn)換也可以被序列化纺阔,還可以一個(gè)(轉(zhuǎn)換)疊另一個(gè)瘸彤,像一串鏈條一樣:

>>>lsi = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)# 初始化一個(gè)LSI轉(zhuǎn)換>>>corpus_lsi = lsi[corpus_tfidf]# 在原始語料庫上加上雙重包裝: bow->tfidf->fold-in-lsi

1

2

這里我們利用潛在語義索引(LSI)將Tf-Idf語料轉(zhuǎn)化為一個(gè)潛在2-D空間(2-D是因?yàn)槲覀冊O(shè)置了num_topics=2)。現(xiàn)在你可能想知道:2潛在維度意味著什么笛钝?讓我們利用models.LsiModel.print_topics()來檢查一下這個(gè)過程到底產(chǎn)生了什么變化吧:

>>>lsi.print_topics(2)topic#0(1.594): -0.703*"trees" + -0.538*"graph" + -0.402*"minors" + -0.187*"survey" + -0.061*"system" + -0.060*"response" + -0.060*"time" + -0.058*"user" + -0.049*"computer" + -0.035*"interface"topic#1(1.476): -0.460*"system" + -0.373*"user" + -0.332*"eps" + -0.328*"interface" + -0.320*"response" + -0.320*"time" + -0.293*"computer" + -0.280*"human" + -0.171*"survey" + 0.161*"trees"

1

2

3

(這些主題將會(huì)記錄在日志中质况,想要了解如何激活日志愕宋,請看開頭的注解)

根據(jù)LSI來看,“tree”结榄、“graph”中贝、“minors”都是相關(guān)的詞語(而且在第一主題的方向上貢獻(xiàn)最多),而第二主題實(shí)際上與所有的詞語都有關(guān)系臼朗。如我們所料邻寿,前五個(gè)文檔與第二個(gè)主題的關(guān)聯(lián)更強(qiáng),而其他四個(gè)文檔與第一個(gè)主題關(guān)聯(lián)最強(qiáng):

>>>fordocincorpus_lsi:# both bow->tfidf and tfidf->lsi transformations are actually executed here, on the fly...print(doc)[(0, -0.066), (1,0.520)]# "Human machine interface for lab abc computer applications"[(0, -0.197), (1,0.761)]# "A survey of user opinion of computer system response time"[(0, -0.090), (1,0.724)]# "The EPS user interface management system"[(0, -0.076), (1,0.632)]# "System and human system engineering testing of EPS"[(0, -0.102), (1,0.574)]# "Relation of user perceived response time to error measurement"[(0, -0.703), (1, -0.161)]# "The generation of random binary unordered trees"[(0, -0.877), (1, -0.168)]# "The intersection graph of paths in trees"[(0, -0.910), (1, -0.141)]# "Graph minors IV Widths of trees and well quasi ordering"[(0, -0.617), (1,0.054)]# "Graph minors A survey"

1

2

3

4

5

6

7

8

9

10

11

模型的持久可以借助save()和load()函數(shù)完成:

>>>lsi.save('/tmp/model.lsi')# same for tfidf, lda, ...>>>lsi = models.LsiModel.load('/tmp/model.lsi')

1

2

下一個(gè)問題可能就該是:這些文檔之間確切的相似度是多少呢视哑?能否將相似性形式化绣否,以便給定一個(gè)文檔,我們能夠根據(jù)其他文檔與該文檔的相似度排序呢挡毅?敬請閱讀下個(gè)教程——《相似度查詢》蒜撮。

可用的轉(zhuǎn)換

Gensim實(shí)現(xiàn)了幾種常見的向量空間模型算法:

詞頻-逆文檔頻(Term Frequency * Inverse Document Frequency, Tf-Idf)

需要一個(gè)詞袋形式(整數(shù)值)的訓(xùn)練語料庫來實(shí)現(xiàn)初始化慷嗜。轉(zhuǎn)換過程中淀弹,他將會(huì)接收一個(gè)向量同時(shí)返回一個(gè)相同維度的向量,在語料庫中非常稀有的屬性的權(quán)重將會(huì)提高庆械。因此薇溃,他會(huì)將整數(shù)型的向量轉(zhuǎn)化為實(shí)數(shù)型的向量,同時(shí)讓維度不變缭乘。而且沐序。你可以選擇是否將返回結(jié)果標(biāo)準(zhǔn)化至單位長度(歐幾里得范數(shù))。

>>> model = tfidfmodel.TfidfModel(bow_corpus, normalize=True)

1

潛在語義索引(Latent Semantic Indexing堕绩,LSI策幼,or sometimes LSA)

將文檔從詞袋或TfIdf權(quán)重空間(更好)轉(zhuǎn)化為一個(gè)低維的潛在空間。對于我們上面用到的玩具級(jí)的語料庫奴紧,我們使用了2潛在維度特姐,但是在真正的語料庫上,推薦200-500的目標(biāo)維度為“金標(biāo)準(zhǔn)”黍氮。[1]

>>>model = lsimodel.LsiModel(tfidf_corpus, id2word=dictionary, num_topics=300)

1

LSI訓(xùn)練的獨(dú)特之處是我們能在任何繼續(xù)“訓(xùn)練”唐含,僅需提供更多的訓(xùn)練文本。這是通過對底層模型進(jìn)行增量更新沫浆,這個(gè)過程被稱為“在線訓(xùn)練”捷枯。正因?yàn)樗倪@個(gè)特性,輸入文檔流可以是無限大——我們能在以只讀的方式使用計(jì)算好的模型的同時(shí)专执,還能在新文檔到達(dá)時(shí)一直“喂食”給LSI“消化”淮捆!

>>>model.add_documents(another_tfidf_corpus)# 現(xiàn)在LSI已經(jīng)使用tfidf_corpus + another_tfidf_corpus進(jìn)行過訓(xùn)練了>>>lsi_vec = model[tfidf_vec]# 將新文檔轉(zhuǎn)化到LSI空間不會(huì)影響該模型>>>...>>>model.add_documents(more_documents)# tfidf_corpus + another_tfidf_corpus + more_documents>>>lsi_vec = model[tfidf_vec]>>>...

1

2

3

4

5

6

有關(guān)在無限大的流中,如何讓LSI逐漸“忘記”舊的觀測結(jié)果,詳情請看gensim.models.lsimodel的幫助文檔攀痊。如果你不怕麻煩桐腌,有幾個(gè)參數(shù)可以控制LSI算法的影響速度、內(nèi)存占用和數(shù)值精度等苟径。

gensim使用一個(gè)新穎的在線增量流分布式訓(xùn)練算法(還挺拗口的…)哩掺,我曾將該方法發(fā)表在[5]中。gensim內(nèi)部執(zhí)行了一個(gè)來自Halko等[4]的隨機(jī)多通道算法(stochastic multi-pass algorithm)來加速核心(in-core)部分的計(jì)算涩笤。參考《在英文維基百科上的實(shí)驗(yàn)》教程了解如何通過計(jì)算機(jī)集群分布式計(jì)算來提高速度。

隨機(jī)映射(Random Projections盒件,RP)

目的在于減小空維度蹬碧。這是一個(gè)非常高效(對CPU和內(nèi)存都很友好)方法,通過拋出一點(diǎn)點(diǎn)隨機(jī)性炒刁,來近似得到兩個(gè)文檔之間的Tfidf距離恩沽。推薦目標(biāo)維度也是成百上千,具體數(shù)值要視你的數(shù)據(jù)集大小而定翔始。

>>>model = rpmodel.RpModel(tfidf_corpus, num_topics=500)

1

隱含狄利克雷分配(Latent Dirichlet Allocation, LDA)

也是將詞袋計(jì)數(shù)轉(zhuǎn)化為一個(gè)低維主題空間的轉(zhuǎn)換罗心。LDA是LSA(也叫多項(xiàng)式PCA)的概率擴(kuò)展,因此LDA的主題可以被解釋為詞語的概率分布城瞎。這些分布式從訓(xùn)練語料庫中自動(dòng)推斷的渤闷,就像LSA一樣。相應(yīng)地脖镀,文檔可以被解釋為這些主題的一個(gè)(軟)混合(又是就像LSA一樣)飒箭。

>>>model = ldamodel.LdaModel(bow_corpus, id2word=dictionary, num_topics=100)

1

gensim使用一個(gè)基于[2]的快速的在線LDA參數(shù)估計(jì)實(shí)現(xiàn),修改并使其可以在計(jì)算機(jī)集群上以分布式模式運(yùn)行蜒灰。

分層狄利克雷過程(Hierarchical Dirichlet Process弦蹂,HDP)

是一個(gè)無參數(shù)貝葉斯方法(注意:這里沒有num_topics參數(shù)):

>>>model = hdpmodel.HdpModel(bow_corpus, id2word=dictionary)

1

gensim使用一種基于[3]的快速在線來實(shí)現(xiàn)。該算法是新加入gensim的强窖,并且還是一種粗糙的學(xué)術(shù)邊緣產(chǎn)品——小心使用凸椿。

增加新的VSM轉(zhuǎn)化(例如新的權(quán)重方案)相當(dāng)平常;參見API參考或者直接參考我們的源代碼以獲取信息與幫助翅溺。

值得一提的是脑漫,這些模型增量模型,無需一次將所有的訓(xùn)練語料庫全部放到內(nèi)存中未巫。在關(guān)心內(nèi)存的同時(shí)窿撬,我還在不斷改進(jìn)分布式計(jì)算,來提高CPU效率叙凡。如果你自覺能夠貢獻(xiàn)一份力量(測試劈伴、提供用例或代碼),請讓我知道

下一個(gè)教程跛璧,我們將會(huì)講《相似度查詢》严里。

[1] Bradford. 2008. An empirical study of required dimensionality for large-scale latent semantic indexing applications.

[2] Hoffman, Blei, Bach. 2010. Online learning for Latent Dirichlet Allocation.

[3] Wang, Paisley, Blei. 2011. Online variational inference for the hierarchical Dirichlet process.

[4] Halko, Martinsson, Tropp. 2009. Finding structure with randomness.

[5] ?eh??ek. 2011. Subspace tracking for Latent Semantic Analysis.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市追城,隨后出現(xiàn)的幾起案子刹碾,更是在濱河造成了極大的恐慌,老刑警劉巖座柱,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迷帜,死亡現(xiàn)場離奇詭異,居然都是意外死亡色洞,警方通過查閱死者的電腦和手機(jī)戏锹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來火诸,“玉大人锦针,你說我怎么就攤上這事≈檬瘢” “怎么了奈搜?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盯荤。 經(jīng)常有香客問我馋吗,道長,這世上最難降的妖魔是什么秋秤? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任耗美,我火速辦了婚禮,結(jié)果婚禮上航缀,老公的妹妹穿的比我還像新娘商架。我一直安慰自己,他們只是感情好芥玉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布蛇摸。 她就那樣靜靜地躺著,像睡著了一般灿巧。 火紅的嫁衣襯著肌膚如雪赶袄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天抠藕,我揣著相機(jī)與錄音饿肺,去河邊找鬼。 笑死盾似,一個(gè)胖子當(dāng)著我的面吹牛敬辣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼溉跃,長吁一口氣:“原來是場噩夢啊……” “哼村刨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撰茎,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤嵌牺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后龄糊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逆粹,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年炫惩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枯饿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诡必,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搔扁,到底是詐尸還是另有隱情爸舒,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布稿蹲,位于F島的核電站扭勉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏苛聘。R本人自食惡果不足惜涂炎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望设哗。 院中可真熱鬧唱捣,春花似錦、人聲如沸网梢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽战虏。三九已至拣宰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烦感,已是汗流浹背巡社。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留手趣,地道東北人晌该。 一個(gè)月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親气笙。 傳聞我的和親對象是個(gè)殘疾皇子次企,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容