2011-04-12 125 views
2

我正在將特徵向量作爲位圖來實現文檔中的文檔。我已經擁有整個語料庫(作爲列表/集)的詞彙表以及每個文檔中的術語列表。Python:高效實現特徵向量

例如,如果語料庫詞彙表爲['a', 'b', 'c', 'd']且文檔d1中的詞語爲['a', 'b', 'd', 'd'],則d1的特徵向量應爲[1, 1, 0, 2]

要生成特徵向量,我需要遍歷語料庫詞彙表並檢查每個詞是否在文檔詞條列表中,然後將該詞位置於文檔特徵向量的正確位置。

什麼是最有效的實現方式?這裏有一些事情我已經考慮:

  • 使用set將使檢查翻譯會員非常有效的,但set■找沒有順序,和特徵向量位需要在排序語料庫詞彙的順序。
  • 對語料庫詞彙使用dict(映射每個詞彙項到任意值,如1)將允許迭代sorted(dict.keys())以便我可以跟蹤索引。但是,我會有空間開銷dict.values()
  • 使用sorted(list)將無法​​檢查成員資格。

StackOverflow會提示什麼?

+0

爲什麼排序列表查找效率低下?你需要比二進制搜索提供的O(log(n))更好嗎? – Cameron 2011-04-12 23:36:29

+0

數萬個術語,數千個文檔。我想盡量減少它,並且哈希允許近乎'O(1)'。 – yavoh 2011-04-12 23:37:37

+0

@yavoh:好,公平點。你可以改變你的數據結構的初始文檔條款是集而不是列表?你確定你確實需要這種特徵向量嗎?你能利用並行化嗎? – Cameron 2011-04-12 23:40:47

回答

2

我認爲最有效的方法是遍歷每個文檔的術語,在(排序的)語料庫中獲取術語的位置並相應地設置該位。

語料庫詞條的排序列表可作爲詞典存儲爲term -> index映射(基本上是inverted index)。

你可以像這樣創建:

corpus = dict(((term, index) for index, term in enumerate(sorted(all_words)))) 

對於每一個文檔,你不得不產生爲特徵向量的0的列表:

num_words = len(corpus) 
fvs = [[0]*num_words for _ in docs] 

然後建立特徵向量會是:

for i, doc_terms in enumerate(docs): 
    fv = fvs[i] 
    for term in doc_terms: 
     fv[corpus[term]] += 1 

測試成員資格沒有開銷,你只需要循環所有文件的所有條款。


這一切都表示,這取決於文集的大小,你應該看看numpyscipy。很可能你會遇到內存問題,並且scipy爲sparse matrices(而不是使用列表列表)提供特殊的數據類型,這可以節省很多內存的
您可以使用與上面所示相同的方法,但不是將數字添加到列表元素,而是將其添加到矩陣元素(例如,行將是文檔和列是語料庫的術語)。

如果您想應用本地或全局加權方案,還可以使用由numpy提供的某些矩陣運算。

我希望這可以讓你開始:)

+0

謝謝!我會研究scipy類。 – yavoh 2011-04-13 00:19:38

+0

@yavoh:你必須考慮兩件事:(a)如何有效地*構建特徵向量。上面的方法應該是非常有效的(實際上我認爲不能做得更好)。 (b)如何有效*存儲*特徵向量。因爲這些向量可能包含很多零點,所以稀疏矩陣就是要走的路... – 2011-04-13 00:24:23

+0

You're right,@Felix Kling。我正在研究使用'scipy.sparse.dok_matrix'。 – yavoh 2011-04-13 00:34:06