我打算用Python实现朴素贝叶斯分类器,并将电子邮件分类为垃圾邮件或非垃圾邮件。我有一个非常稀疏且长的数据集,包含许多条目。每个条目如下所示:
1 9:3 94:1 109:1 163:1 405:1 406:1 415:2 416:1 435:3 436:3 437:4 …
其中1是标签(垃圾邮件,非垃圾邮件),每个对对应一个单词及其频率。例如,9:3对应单词9,在此电子邮件样本中出现3次。
我需要读取这个数据集并将其存储在一个结构中。由于这是一个非常大且稀疏的数据集,我正在寻找一个整洁的数据结构来存储以下变量:
- 每封电子邮件的索引
- 其标签(1或-1)
- 每个电子邮件中单词及其频率
- 我还需要创建一个包含所有单词及其频率以及标签信息的语料库
对于这样的数据结构,有什么建议吗?
回答:
我会生成一个类
class Document(object): def __init__(self, index, label, bowdict): self.index = index self.label = label self.bowdict = bowdict
你将你的稀疏向量存储在bowdict
中,例如
{ 9:3, 94:1, 109:1, ... }
并将所有数据保存在一个Document
列表中
要获取具有给定标签的所有文档的聚合信息:
from collections import defaultdictdef aggregate(docs, label): bow = defaultdict(int) for doc in docs: if doc.label == label: for (word, counter) in doc.bowdict.items(): bow[word] += counter return bow
你可以使用cPickle
模块来持久化所有数据。
另一种方法是使用http://docs.scipy.org/doc/scipy/reference/sparse.html。你可以将一个bow向量表示为一个稀疏矩阵的一行。如果你想聚合bows,你只需将它们相加。这可能比上面的简单解决方案快得多。
此外,你可以将所有稀疏文档存储在一个大型矩阵中,其中一个Document实例持有对矩阵的引用,以及与关联行对应的行索引。