Python:高效地实现特征向量

Python:高效地实现特征向量,python,hash,dictionary,Python,Hash,Dictionary,我正在将特征向量实现为语料库中文档的位图。我已经有了整个语料库的词汇表(作为一个列表/集合)和每个文档中的术语列表 例如,如果语料库词汇是['a','b','c','d'],文档d1中的术语是['a','b','d','d'],则d1的特征向量应该是[1,1,0,2] 要生成特征向量,我需要遍历语料库词汇表,检查每个术语是否在文档术语列表中,然后将位设置在文档特征向量的正确位置 实现这一点最有效的方法是什么?以下是我考虑过的一些事情: 使用set将使检查vocab成员非常有效,但是sets没有

我正在将特征向量实现为语料库中文档的位图。我已经有了整个语料库的词汇表(作为一个列表/集合)和每个文档中的术语列表

例如,如果语料库词汇是
['a','b','c','d']
,文档d1中的术语是
['a','b','d','d']
,则d1的特征向量应该是
[1,1,0,2]

要生成特征向量,我需要遍历语料库词汇表,检查每个术语是否在文档术语列表中,然后将位设置在文档特征向量的正确位置

实现这一点最有效的方法是什么?以下是我考虑过的一些事情:

  • 使用
    set
    将使检查vocab成员非常有效,但是
    set
    s没有顺序,并且特征向量位需要按照已排序的语料库词汇表的顺序
  • 对语料库vocab使用
    dict
    (将每个vocab术语映射到任意值,如
    1
    )将允许对
    排序(dict.keys())
    进行迭代,以便我可以跟踪索引。但是,我会有
    dict.values()
    的空间开销
  • 使用
    排序(列表)
    检查成员资格将效率低下

StackOverflow会有什么建议?

我认为最有效的方法是循环检查每个文档的术语,获取术语在(排序的)语料库中的位置,并相应地设置位

语料库术语的排序列表可以通过
term->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
在测试成员资格时没有任何开销,您只需遍历所有文档的所有条款即可


所有这些都说明了,根据语料库的大小,您应该查看和。您可能会遇到内存问题,而scipy为您提供了特殊的数据类型(而不是使用列表列表),这样可以节省大量内存。
您可以使用如上所示的相同方法,但不是将数字添加到列表元素,而是将其添加到矩阵元素(例如,行将是文档,列将是语料库的术语)

如果要应用局部或全局加权方案,还可以使用numpy提供的一些矩阵运算


我希望这能让您开始:)

为什么排序列表查找效率低下?你需要比二进制搜索提供的O(log(n))更好的搜索吗?数万个术语,数千个文档。我想将其最小化,哈希允许几乎
O(1)
@yavoh:好的,公平点。您能否将初始文档术语的数据结构更改为集合而不是列表?你确定你真的需要这样的特征向量吗?你能利用并行化吗?我忘了提到我需要保存术语的频率,而不仅仅是术语的存在,我的错误-我已经更新了原始问题。所以,一套就不行了。@yavoh:Aha,这完全改变了它;-)谢谢我将研究scipy类。@yavoh:有两件事你必须考虑:(a)如何有效地构建特征向量。上述方法应该相当有效(实际上我认为没有人能做得更好)。(b) 如何有效地存储特征向量。因为这些向量很可能包含很多零,所以稀疏矩阵是一种方法……你说得对,@Felix Kling。我正在研究如何使用
scipy.sparse.dok_矩阵