文本挖掘從小白到精通(二):料庫和詞向量空間

2 評(píng)論 8505 瀏覽 12 收藏 28 分鐘

寫筆者最近在梳理自己的文本挖掘知識(shí)結(jié)構(gòu),借助gensim、sklearn、keras等庫的文檔做了些擴(kuò)充,會(huì)陸陸續(xù)續(xù)介紹文本向量化、tfidf、主題模型、word2vec,既會(huì)涉及理論,也會(huì)有詳細(xì)的代碼和案例進(jìn)行講解,希望在梳理自身知識(shí)體系的同時(shí)也能對(duì)想學(xué)習(xí)文本挖掘的朋友有一點(diǎn)幫助,這是筆者寫該系列的初衷。

在本文中,筆者將會(huì)緊接著上文提及的3個(gè)概念,拓展到文本挖掘中一個(gè)重要的概念 —(文本)向量空間,它是將自然語言轉(zhuǎn)化為機(jī)器可識(shí)別符號(hào)的關(guān)鍵一步,文本相似度、文本聚類、文本分類等實(shí)際應(yīng)用皆以此為基礎(chǔ)。

培養(yǎng)碼代碼的好習(xí)慣,設(shè)置日志,打印程序運(yùn)行中的細(xì)節(jié),以便調(diào)試代碼。

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
import os 
import tempfile
TEMP_FOLDER = tempfile.gettempdir()
print('文件夾"{}" 將被用來存儲(chǔ)語料和臨時(shí)性的字典'.format(TEMP_FOLDER))

文件夾”C:UsershpAppDataLocalTemp” 將被用來存儲(chǔ)語料和臨時(shí)性的字典

一、從字符串到向量(From Strings to Vectors)

這次,筆者還是使用之前關(guān)于“知識(shí)圖譜”報(bào)道的標(biāo)題語料庫作為示例:

from gensim import corpora
import jieba

2019-05-06 09:59:43,964 : INFO : ‘pattern’ package not found; tag filters are not available for English

根據(jù)打印出的日志可知,’pattern’沒正確安裝上,這個(gè)庫是自然語言處理里一個(gè)很棒的庫,不過目前沒怎么更新了,且對(duì)中文的支持不給力,所以不影響接下來的分析。

jieba.add_word('知識(shí)圖譜') #防止“知識(shí)圖譜”被切錯(cuò)詞
docs = ['商業(yè)新知:知識(shí)圖譜為內(nèi)核,構(gòu)建商業(yè)創(chuàng)新服務(wù)完整生態(tài)。',
'如何更好利用知識(shí)圖譜技術(shù)做反欺詐? 360金融首席數(shù)據(jù)科學(xué)家沈赟開講。',
'知識(shí)管理 | 基于知識(shí)圖譜的國際知識(shí)管理領(lǐng)域可視化分析。',
'一文詳解達(dá)觀數(shù)據(jù)知識(shí)圖譜技術(shù)與應(yīng)用。',
'知識(shí)圖譜技術(shù)落地金融行業(yè)的關(guān)鍵四步。',
'一文讀懂知識(shí)圖譜的商業(yè)應(yīng)用進(jìn)程及技術(shù)背景。',
'海云數(shù)據(jù)CPO王斌:打造大數(shù)據(jù)可視分析與AI應(yīng)用的高科技企業(yè)。',
'智能產(chǎn)業(yè)|《人工智能標(biāo)準(zhǔn)化白皮書2018》帶來創(chuàng)新創(chuàng)業(yè)新技術(shù)標(biāo)準(zhǔn)。',
'國家語委重大科研項(xiàng)目“中華經(jīng)典詩詞知識(shí)圖譜構(gòu)建技術(shù)研究”開題。',
'最全知識(shí)圖譜介紹:關(guān)鍵技術(shù)、開放數(shù)據(jù)集、應(yīng)用案例匯總。',
'中譯語通Jove Mind知識(shí)圖譜平臺(tái) 引領(lǐng)企業(yè)智能化發(fā)展。',
'知識(shí)圖譜:知識(shí)圖譜賦能企業(yè)數(shù)字化轉(zhuǎn)型,為企業(yè)升級(jí)轉(zhuǎn)型注入新能量。']

再對(duì)文本進(jìn)行分詞,用空格隔開變成字符串,方便進(jìn)行下一步的處理:

documents = [' '.join(jieba.lcut(i)) for i in docs]
print(documents)

[‘商業(yè) 新知 : 知識(shí)圖譜 為 內(nèi)核 , 構(gòu)建 商業(yè) 創(chuàng)新 服務(wù) 完整 生態(tài) 。’,

‘如何 更好 利用 知識(shí)圖譜 技術(shù) 做 反 欺詐 ? 360 金融 首席 數(shù)據(jù) 科學(xué)家 沈赟 開講 。’,

‘知識(shí) 管理 | 基于 知識(shí)圖譜 的 國際 知識(shí) 管理 領(lǐng)域 可視化 分析 。’,

‘一文 詳解 達(dá)觀 數(shù)據(jù) 知識(shí)圖譜 技術(shù) 與 應(yīng)用 。’,

‘知識(shí)圖譜 技術(shù) 落地 金融 行業(yè) 的 關(guān)鍵 四步 。’,

‘一文 讀懂 知識(shí)圖譜 的 商業(yè) 應(yīng)用 進(jìn)程 及 技術(shù) 背景 。’,

‘海云 數(shù)據(jù) CPO 王斌 : 打造 大 數(shù)據(jù) 可視 分析 與 AI 應(yīng)用 的 高科技 企業(yè) 。’,

‘智能 產(chǎn)業(yè) | 《 人工智能 標(biāo)準(zhǔn)化 白皮書 2018 》 帶來 創(chuàng)新 創(chuàng)業(yè) 新 技術(shù)標(biāo)準(zhǔn) 。’,

‘國家語委 重大 科研項(xiàng)目 “ 中華 經(jīng)典 詩詞 知識(shí)圖譜 構(gòu)建 技術(shù) 研究 ” 開題 。’,

‘最全 知識(shí)圖譜 介紹 : 關(guān)鍵技術(shù) 、 開放 數(shù)據(jù) 集 、 應(yīng)用 案例 匯總 。’,

‘中譯 語通 Jove Mind 知識(shí)圖譜 平臺(tái) 引領(lǐng) 企業(yè) 智能化 發(fā)展 。’,

‘知識(shí)圖譜 : 知識(shí)圖譜 賦能 企業(yè) 數(shù)字化 轉(zhuǎn)型 , 為 企業(yè) 升級(jí) 轉(zhuǎn)型 注入 新 能量 。’]

這是一個(gè)包含12個(gè)文檔的小型語料,每個(gè)文檔僅包含1個(gè)語句。

首先,對(duì)這些文檔進(jìn)行分詞處理,移除停用詞,并去掉那些僅在本語料中出現(xiàn)一次的詞匯:

from pprint import pprint
from collections import defaultdict
# 移除常用詞以及分詞

stoplist = [i.strip() for i in open('datasets/stopwords_zh.txt',encoding='utf-8').readlines()]
texts = [[word for word in document.lower().split() if word not in stoplist]?for document in documents]# 移除僅出現(xiàn)一次的詞匯
frequency = defaultdict(int)
for text in texts:for token in text:
frequency[token] += 1
texts = [[token for token in text if frequency[token] > 1] for text in texts]
#使打印的格式更齊整
pprint(texts)

[[‘商業(yè)’, ‘知識(shí)圖譜’, ‘商業(yè)’, ‘創(chuàng)新’],

[‘知識(shí)圖譜’, ‘技術(shù)’, ‘金融’, ‘數(shù)據(jù)’],

[‘知識(shí)’, ‘管理’, ‘知識(shí)圖譜’, ‘知識(shí)’, ‘管理’, ‘分析’],

[‘一文’, ‘數(shù)據(jù)’, ‘知識(shí)圖譜’, ‘技術(shù)’],

[‘知識(shí)圖譜’, ‘技術(shù)’, ‘金融’],

[‘一文’, ‘知識(shí)圖譜’, ‘商業(yè)’, ‘技術(shù)’],

[‘數(shù)據(jù)’, ‘數(shù)據(jù)’, ‘分析’, ‘企業(yè)’], [‘創(chuàng)新’],

[‘知識(shí)圖譜’, ‘技術(shù)’],

[‘知識(shí)圖譜’, ‘數(shù)據(jù)’],

[‘知識(shí)圖譜’, ‘企業(yè)’],

[‘知識(shí)圖譜’, ‘知識(shí)圖譜’, ‘企業(yè)’, ‘轉(zhuǎn)型’, ‘企業(yè)’, ‘轉(zhuǎn)型’]]

處理文檔的方式需要因時(shí)制宜,隨機(jī)應(yīng)變,尤其是在不同的應(yīng)用場(chǎng)景中,比如電商評(píng)論、博客長文以及微博內(nèi)容都需要使用不同的預(yù)處理方法,筆者會(huì)在后面的文章中提及這些技巧。在這里,基于上面的分詞,筆者僅用空格分開,然后對(duì)語句中的西文詞匯進(jìn)行“小寫化(Lowercasing)”。

機(jī)器是看不懂人類的自然語言(自然語言通常是指一種自然地隨文化演化的語言。例如:英語、漢語、日語為自然語言的例子,而世界語則為人造語言,即是一種為某些特定目的而創(chuàng)造的語言),若要機(jī)器“讀懂”自然語言,則需要將其轉(zhuǎn)換為機(jī)器可識(shí)別的符號(hào),比如”0″和”1″,且這種轉(zhuǎn)換的過程中需要最大限度保留自然語言特有的語義特征,這是一個(gè)很有難度的任務(wù)。

在這里,筆者介紹一種常見的文本表示方法——稱為詞袋模型,即Bag-of-Words)。

在詞袋模型模型下,像是句子或是文件這樣的文字可以用一個(gè)袋子裝著這些詞的方式表現(xiàn),這種表現(xiàn)方式不考慮文法以及詞的順序。

https://baike.baidu.com/item/%E8%AF%8D%E8%A2%8B%E6%A8%A1%E5%9E%8B/22776998?fr=aladdin

后面還會(huì)有很多不同的文本表示方法,比如TF-IDF、LSA、LSI、LDA、HDP、NMF、Word2vec等。但是,請(qǐng)記住,不同的應(yīng)用場(chǎng)景需要不同的文本特征,沒有百試不爽的方法,并且,請(qǐng)一如既往的記住這句名言:

垃圾入,垃圾出(garbage in, garbage out)。

使用詞袋模型將多個(gè)文檔轉(zhuǎn)換為向量,每個(gè)文檔由一個(gè)向量表示,其中向量元素“i”表示第i個(gè)單詞出現(xiàn)在文檔中的次數(shù)。

僅通過它們的(整型)id來表征詞匯是有利的, 問題和ID之間的映射稱為字典(dictionary):

dictionary = corpora.Dictionary(texts)
dictionary.save(os.path.join(TEMP_FOLDER, 'deerwester.dict')) # 保存字典,以備后續(xù)查找之用print(dictionary)

2019-05-06 15:58:09,861 : INFO : adding document #0 to Dictionary(0 unique tokens: [])2019-05-06 15:58:09,867 : INFO : built Dictionary(12 unique tokens: [‘創(chuàng)新’, ‘商業(yè)’, ‘知識(shí)圖譜’, ‘技術(shù)’, ‘數(shù)據(jù)’]…)

12 documents (total 42 corpus positions)

2019-05-06 15:58:09,873 : INFO : saving Dictionary object under C:Users/hp/AppDataLocal/Tempdeerwester.dict, separately None

2019-05-06 15:58:09,879 : INFO : saved C:UsershpAppDataLocalTempdeerwester.dict

Dictionary(12 unique tokens: [‘創(chuàng)新’, ‘商業(yè)’, ‘知識(shí)圖譜’, ‘技術(shù)’, ‘數(shù)據(jù)’]…)

在這里,我們通過gensim.corpora.dictionary.Dictionary這個(gè)類為處理過的語料庫中出現(xiàn)的每個(gè)詞匯分配一個(gè)獨(dú)一無二的整數(shù)ID 。 這會(huì)掃描整個(gè)文本,統(tǒng)計(jì)所有的詞匯計(jì)數(shù)和詞匯相關(guān)數(shù)據(jù)。 最后,我們看到在處理的語料庫中有12個(gè)不同的詞匯,這意味著每個(gè)文檔將由12個(gè)數(shù)字表示(即12-D向量)。

下面,查看每個(gè)詞匯與其對(duì)應(yīng)ID之間的映射關(guān)系:

print(dictionary.token2id)

{‘創(chuàng)新’: 0, ‘商業(yè)’: 1, ‘知識(shí)圖譜’: 2, ‘技術(shù)’: 3, ‘數(shù)據(jù)’: 4, ‘金融’: 5, ‘分析’: 6, ‘知識(shí)’: 7, ‘管理’: 8, ‘一文’: 9, ‘企業(yè)’: 10, ‘轉(zhuǎn)型’: 11}

將分詞后的文檔實(shí)際轉(zhuǎn)換為向量:

new_doc = "知識(shí)圖譜 為 企業(yè) 轉(zhuǎn)型 助力"
new_vec = dictionary.doc2bow(new_doc.lower().split())
print(new_vec) # “為”、“助力”等詞匯未出現(xiàn)在字典中,因而被忽略

[(2, 1), (10, 1), (11, 1)]

函數(shù)doc2bow()只是計(jì)算每個(gè)不同詞匯的出現(xiàn)次數(shù),將詞匯轉(zhuǎn)換為整數(shù)詞匯id,并將結(jié)果作為一個(gè)詞袋(bag-of-words)——一個(gè)稀疏向量返回,形式為( word_id1,word_count1),( word_id2,word_count2),( word_id3,word_count3)…

在token_id中,“創(chuàng)新”對(duì)應(yīng)的為0,“商業(yè)”為1,…,’轉(zhuǎn)型’為11。因而,新文檔“知識(shí)圖譜 為 企業(yè) 轉(zhuǎn)型 助力(知識(shí)圖譜為企業(yè)轉(zhuǎn)型助力)”將被轉(zhuǎn)換為[(2, 1), (10, 1), (11, 1)]。 “知識(shí)圖譜”、“企業(yè)”、“轉(zhuǎn)型” 出現(xiàn)在詞典中并出現(xiàn)一次。

因此,它們?cè)谙∈柘蛄恐蟹謩e變?yōu)?2, 1), (10, 1), (11, 1)。 “為”、“轉(zhuǎn)型”、“助力”等詞匯在字典中不存在,因此不會(huì)出現(xiàn)在稀疏向量中。詞匯計(jì)數(shù)為0的詞匯不會(huì)出現(xiàn)在稀疏向量中,并且稀疏向量中將永遠(yuǎn)不會(huì)出現(xiàn)像(3,0)這樣的元素。

對(duì)于熟悉scikit-learn的人來說,doc2bow()與在CountVectorizer上調(diào)用transform()有類似的作用(http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html)。doc2bow()也可以像fit_transform()那樣運(yùn)作。

相關(guān)詳細(xì)信息,請(qǐng)參閱 gensim API Doc

corpus = [dictionary.doc2bow(text) for text in texts]
corpora.MmCorpus.serialize(os.path.join(TEMP_FOLDER, 'deerwester.mm'), corpus) #保存到本地,以作后用
for c in corpus:
print(c)

2019-05-06 16:00:28,683 : INFO : storing corpus in Matrix Market format to C:Users/hp/AppData/Local/Tempdeerwester.mm

2019-05-06 16:00:28,688 : INFO : saving sparse matrix to C:Users/hp/AppData/Local/Temp/deerwester.mm

2019-05-06 16:00:28,690 : INFO : PROGRESS: saving document

2019-05-06 16:00:28,693 : INFO : saved 12×12 matrix, density=24.306% (35/144)

2019-05-06 16:00:28,695 : INFO : saving MmCorpus index to C:UsershpAppDataLocalTempdeerwester.mm.index

[(0, 1), (1, 2), (2, 1)]

[(2, 1), (3, 1), (4, 1), (5, 1)]

[(2, 1), (6, 1), (7, 2), (8, 2)]

[(2, 1), (3, 1), (4, 1), (9, 1)]

[(2, 1), (3, 1), (5, 1)]

[(1, 1), (2, 1), (3, 1), (9, 1)]

[(4, 2), (6, 1), (10, 1)]

[(0, 1)]

[(2, 1), (3, 1)][(2, 1), (4, 1)]

[(2, 1), (10, 1)]

[(2, 2), (10, 2), (11, 2)]

到目前為止,應(yīng)該清楚的是,帶有id = 10的向量特征表示文檔中出現(xiàn)“企業(yè)”一詞的次數(shù)——在這12個(gè)文檔中, 只有倒數(shù)前2個(gè)和和倒數(shù)第6個(gè)的值為1,其他皆為0。

二、語料庫流(Corpus Streaming)——每次僅調(diào)用一個(gè)文檔

請(qǐng)注意,上面的語料(corpus)完全駐留在內(nèi)存中,作為普通的Python列表而存在。 在這個(gè)簡(jiǎn)單的例子中,它并不重要,只是為了闡述方便。讓我們假想,手頭的語料庫中有數(shù)千萬個(gè)文檔,要將所有這些文檔都存儲(chǔ)在RAM中是行不通的,這會(huì)消耗大量的計(jì)算資源,速度奇慢!

相反,我們假設(shè)文檔存儲(chǔ)在本地的單個(gè)文件中,每行一個(gè)文檔。 Gensim只要求語料庫在需要使用時(shí),能夠一次返回一個(gè)文檔向量:

from smart_open import smart_open
class MyCorpus(object):
def __iter__(self):
for line in smart_open('datasets/mycorpus.txt', 'r',encoding='utf-8'):
# 假設(shè)每一行一個(gè)文檔,用jieba進(jìn)行分詞
yield dictionary.doc2bow(' '.join(jieba.lcut(line)).lower().split())

每個(gè)文檔占用單個(gè)文件中一行的假設(shè)并不重要,你可以設(shè)計(jì)__iter__函數(shù)以適合你的特定輸入格式,比如文檔目錄、待解析的XML、可訪問的網(wǎng)絡(luò)節(jié)點(diǎn)……只需解析你的輸入以檢索每個(gè)文檔中的所用詞匯,然后通過字典將這些詞匯轉(zhuǎn)換為它們對(duì)應(yīng)的整數(shù)ID,并在__iter__中產(chǎn)生具有生成器屬性的稀疏向量。

corpus_memory_friendly = MyCorpus() #不需要將語料載入到內(nèi)存中!
print(corpus_memory_friendly)

<__main__.MyCorpus object at 0x00000160C6575320>

現(xiàn)在,corpus_memory_friendly是一個(gè)對(duì)象。 我們沒有定義任何打?。╬rint)方式,因此print只輸出對(duì)象在內(nèi)存中的地址, 這看起來沒啥用。 要查看其中的向量構(gòu)成,需要遍歷語料庫,并打印每個(gè)文檔向量(一次一個(gè)):

for vector in corpus_memory_friendly: #每次載入一個(gè)文檔向量
print(vector)

[(0, 1), (1, 2), (2, 1), (3, 1)]

[(2, 1), (3, 1), (4, 1), (5, 1), (6, 1)]

[(2, 1), (3, 3), (7, 1), (8, 2)]

[(2, 1), (3, 1), (4, 1), (5, 1), (9, 1)]

[(2, 1), (3, 1), (4, 1), (6, 1)]

[(1, 1), (2, 1), (3, 1), (4, 1), (9, 1)]

[(5, 2), (7, 1), (10, 1)]

[(0, 1)]

[(2, 1), (3, 1), (4, 1)]

[(2, 1), (3, 1), (5, 1)]

[(2, 1), (3, 1), (10, 1)]

[(2, 2), (3, 2), (10, 1)]

盡管輸出與普通的Python列表的輸出相同,但此時(shí)的語料庫對(duì)內(nèi)存更友好——一次最多只有一個(gè)向量駐留在RAM中, 現(xiàn)在,你的語料庫想用多大就用多大,哪怕是成千上萬個(gè)文檔,只是速度稍慢罷了。

我們將使用mycorpus.txt這個(gè)文件來創(chuàng)建字典(Dictionary),但不是將整個(gè)文件加載到本地內(nèi)存中。 然后,我們將過濾掉語料中的停用詞以及詞頻為1的詞匯,從而得到“凈化”后的語料。

請(qǐng)記住,dictionary.filter_tokens(或者dictionary.add_document)將調(diào)用dictionary.compactify()來刪除詞匯id序列中的間隙,空置的占位符(””)將會(huì)被剔除。

from six import iteritems
from smart_open import smart_open???
#收集所有詞匯的統(tǒng)計(jì)信息
dictionary = corpora.Dictionary(''.join(jieba.lcut(line)).lower().split() for line in
smart_open('datasets/mycorpus.txt','r',encoding='utf-8'))?
?
#停用詞和低頻詞(這里指僅出現(xiàn)1次的詞匯)的ID集合
stop_ids = [dictionary.token2id[stopword] for stopword in stoplist 
if stopword in dictionary.token2id]
once_ids = [tokenid for tokenid, docfreq in iteritems(dictionary.dfs) if docfreq == 1]?

#真正實(shí)施去停用詞和低頻次的操作
dictionary.filter_tokens(stop_ids + once_ids)
print(dictionary)

2019-05-06 15:44:52,297 : INFO : adding document #0 to Dictionary(0 unique tokens: [])

2019-05-06 15:44:52,303 : INFO : built Dictionary(100 unique tokens: [‘,’, ‘:’, ‘。’, ‘為’, ‘內(nèi)核’]…) from 12 documents (total 164 corpus positions)

Dictionary(10 unique tokens: [‘創(chuàng)新’, ‘商業(yè)’, ‘圖譜’, ‘知識(shí)’, ‘技術(shù)’]…)

到這里,詞袋表示(Bag-of-words Representation)的原理和操作就說完了。 當(dāng)然,我們用這種語料庫可以做什么是另一個(gè)問題; 計(jì)算不同單詞的出現(xiàn)頻率可能是有用的,但在實(shí)際場(chǎng)景中,這還不夠。

事實(shí)證明,我們經(jīng)常需要對(duì)這個(gè)簡(jiǎn)單的表示進(jìn)行轉(zhuǎn)換(Transformation),之后才能進(jìn)行文檔相似度、文本聚類或者文本分類這樣的任務(wù)。 轉(zhuǎn)換后面會(huì)提到,但在此之前,讓我們將注意力集中在語料庫持久性(Corpus Persistency)上。

三、語料格式(Corpus Formats)

存在幾種用于將向量空間(Vector Space)語料庫(向量序列)序列化到本地的文件格式。Gensim通過前面提到的流式語料庫接口(Streaming Corpus Interface)實(shí)現(xiàn):以惰性方式(A Lazy Fashion)從本地讀取大量語料,一次一個(gè)文檔,而不是一次性將整個(gè)語料庫讀入本地內(nèi)存中,這在語料庫極為龐大時(shí)是很折騰電腦的。

其中,一種比較值得注意的文件格式是Matrix Market格式(http://math.nist.gov/MatrixMarket/formats.html)。

下面,將文檔以Matrix Market格式保存:

#創(chuàng)建一個(gè)包含2個(gè)文檔的微小語料,以一個(gè)python列表呈現(xiàn)
corpus = [[(1, 0.5)], []] # 其中一個(gè)文檔故意搞成空的
corpora.MmCorpus.serialize(os.path.join(TEMP_FOLDER, 'corpus.mm'), corpus)

2019-05-06 16:36:54,265 : INFO : storing corpus in Matrix Market format to C:Users/hp/AppData/Local/Temp/corpus.mm

2019-05-06 16:36:54,281 : INFO : saving sparse matrix to C:Users/hp/AppData/Local/Temp/corpus.mm

2019-05-06 16:36:54,285 : INFO : PROGRESS: saving document #

2019-05-06 16:36:54,290 : INFO : saved 2×2 matrix, density=25.000% (1/4)

2019-05-06 16:36:54,293 : INFO : saving MmCorpus index to C:Users/hp/AppData/Local/Temp/corpus.mm.index

其他的存儲(chǔ)格式還有Joachim’s SVMlight format(http://svmlight.joachims.org/)、Blei’s LDA-C format(http://www.cs.columbia.edu/~blei/lda-c/) 和GibbsLDA++ format(http://gibbslda.sourceforge.net/)。

corpora.SvmLightCorpus.serialize(os.path.join(TEMP_FOLDER, 'corpus.svmlight'), corpus)
corpora.BleiCorpus.serialize(os.path.join(TEMP_FOLDER, 'corpus.lda-c'), corpus)
corpora.LowCorpus.serialize(os.path.join(TEMP_FOLDER, 'corpus.low'), corpus)

反向操作,從Matrix Market文件加載語料庫迭代器(Corpus Iterator):

corpus = corpora.MmCorpus(os.path.join(TEMP_FOLDER, 'corpus.mm'))

語料庫對(duì)象是流式的(Streams),因此,我們通常無法直接打印它們,只有通過遍歷才能看到其中的元素:

print(corpus)

MmCorpus(2 documents, 2 features, 1 non-zero entries)

通過迭代器列表化來查看語料庫中的元素:

# 一種打印語料庫的方式是 --- 將其整個(gè)載入內(nèi)存中
print(list(corpus)) # 調(diào)用 list() 能將任何序列轉(zhuǎn)化為普通的Python list

[[(1,0.5)],[]]

或者這樣:

# 另一種方法:一次打印一個(gè)文檔
for doc in corpus:
print(doc)

[(1, 0.5)][]

顯然,第二種方式對(duì)內(nèi)存更友好,但是出于測(cè)試和開發(fā)的目的,沒有什么比調(diào)用list(corpus)更簡(jiǎn)單、快捷!。

接下來,以Blei的LDA-C格式保存相同的Matrix Market文檔流:

corpora.BleiCorpus.serialize(os.path.join(TEMP_FOLDER, 'corpus.lda-c'), corpus)

通過這種方式,gensim也可以用作內(nèi)存高效的I / O格式轉(zhuǎn)換工具:只需使用一種格式加載文檔流,然后立即以另一種格式進(jìn)行保存。

四、與NumPy、SciPy的兼容性

Gensim還囊括許多高效且實(shí)用的函數(shù),可以在(http://radimrehurek.com/gensim/matutils.html)看到,通過這些函數(shù),我們可以輕松的進(jìn)行numpy矩陣的轉(zhuǎn)換:

import gensim
import numpy as np
numpy_matrix = np.random.randint(10, size=[5,2])
numpy_matrix

array([[0, 4],

[0, 7],

[8, 2],

[7, 0],

[2, 1]])

corpus = gensim.matutils.Dense2Corpus(numpy_matrix)
numpy_matrix_dense = gensim.matutils.corpus2dense(corpus, num_terms=10)
numpy_matrix_dense

array([[0., 4.],

[0., 7.],

[8., 2.],

[7., 0.],

[2., 1.],

[0., 0.],

[0., 0.],

[0., 0.],

[0., 0.],

[0., 0.]], dtype=float32)

與scipy.sparse矩陣相互轉(zhuǎn)換:

import scipy.sparse
scipy_sparse_matrix = scipy.sparse.random(5,2)
scipy_sparse_matrix

<5×2 sparse matrix of type ‘<class ‘numpy.float64′>’ with 0 stored elements in COOrdinate format>

corpus = gensim.matutils.Sparse2Corpus(scipy_sparse_matrix)
corpus

<gensim.matutils.Sparse2Corpus at 0x160c65759e8>

scipy_csc_matrix = gensim.matutils.corpus2csc(corpus)
scipy_csc_matrix

<0x2 sparse matrix of type ‘<class ‘numpy.float64′>’ with 0 stored elements in Compressed Sparse Column format>

要獲得完整的參考(想要將字典的規(guī)模精簡(jiǎn)下以節(jié)約內(nèi)存??jī)?yōu)化語料庫和NumPy / SciPy數(shù)組之間的轉(zhuǎn)換?),請(qǐng)參閱gensim的API文檔。

在下一篇文章中,筆者會(huì)接著本次的主題,說說關(guān)于主題模型和文本數(shù)據(jù)轉(zhuǎn)換,即TF-IDF模型、潛在語義索引(LSI)、隨機(jī)映射(Random Projections)、隱狄利克雷分配模型(Latent Dirichlet Allocation, LDA)、層次狄利克雷過程(Hierarchical Dirichlet Process,HDP)的教程。

#專欄作家

蘇格蘭折耳喵(微信公眾號(hào):Social Listening與文本挖掘),人人都是產(chǎn)品經(jīng)理專欄作家,數(shù)據(jù)PM一只,擅長數(shù)據(jù)分析和可視化表達(dá),熱衷于用數(shù)據(jù)發(fā)現(xiàn)洞察,指導(dǎo)實(shí)踐。

本文原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載。

題圖來自Unsplash,基于CC0協(xié)議

更多精彩內(nèi)容,請(qǐng)關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號(hào)或下載App
評(píng)論
評(píng)論請(qǐng)登錄
  1. 請(qǐng)問數(shù)據(jù)是用Python代碼爬的還是用什么工具爬的呀

    來自廣東 回復(fù)
    1. 異步爬蟲爬取的,半小時(shí)內(nèi)搞定,如果是類似八爪魚的采集工具,你得爬半個(gè)月。。。

      來自江蘇 回復(fù)