2011-04-12 55 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