【问题标题】:Understanding _count_vocab method in sklearn.feature_extraction.text's CountVectorizer class了解 sklearn.feature_extraction.text 的 CountVectorizer 类中的 _count_vocab 方法
【发布时间】:2013-11-29 05:13:10
【问题描述】:

我正在使用 CountVectorizer 中的 fit_transform 方法,并且正在阅读代码以尝试了解它在做什么。我对 CountVectorizer 中的 _count_vocab 方法有点困惑,特别是在嵌套的 for 循环下。对于原始文档,我有一个句子列表,并且 fixed_vocab = False。

def _count_vocab(self, raw_documents, fixed_vocab):
    """Create sparse feature matrix, and vocabulary where fixed_vocab=False"""
    if fixed_vocab:
        vocabulary = self.vocabulary_
    else:
        # Add a new value when a new vocabulary item is seen
        vocabulary = defaultdict(None)
        vocabulary.default_factory = vocabulary.__len__

    analyze = self.build_analyzer()
    j_indices = _make_int_array()
    indptr = _make_int_array()
    indptr.append(0)
    for doc in raw_documents:
        for feature in analyze(doc):
            try:
                j_indices.append(vocabulary[feature])
            except KeyError:
                # Ignore out-of-vocabulary items for fixed_vocab=True
                continue
        indptr.append(len(j_indices))
    if not fixed_vocab:
        # disable defaultdict behaviour
        vocabulary = dict(vocabulary)
        if not vocabulary:
            raise ValueError("empty vocabulary; perhaps the documents only"
                             " contain stop words")

    # some Python/Scipy versions won't accept an array.array:
    if j_indices:
        j_indices = np.frombuffer(j_indices, dtype=np.intc)
    else:
        j_indices = np.array([], dtype=np.int32)
    indptr = np.frombuffer(indptr, dtype=np.intc)
    values = np.ones(len(j_indices))

    X = sp.csr_matrix((values, j_indices, indptr),
                      shape=(len(indptr) - 1, len(vocabulary)),
                      dtype=self.dtype)
    X.sum_duplicates()
    return vocabulary, X

这里的词汇表是一个空的 defaultdict 对象。因此 j_indices 不会附加元素,因为词汇表是空的,所以词汇表[feature] 返回一个错误并且错误被忽略,继续下一个 for 循环迭代。它将继续对 raw_documents 中的所有 doc 以及由 analyze(doc) 返回的标记中的所有功能执行此操作。在这个 j_indices 和 indptr 的末尾是空的 array.array 对象。

我以为 _count_vocab 会在遇到新的词汇时创建自己的词汇对象并附加值,但它看起来不像。

在这种情况下,我应该提供我自己的词汇表吗?既然我没有,我在哪里可以得到一本单词词典?

感谢您的帮助。

【问题讨论】:

    标签: python scikit-learn feature-extraction


    【解决方案1】:

    vocabulary[feature]返回错误,错误被忽略

    没有错误,因为 vocabularydefaultdict。会发生什么

    >>> vocabulary = defaultdict(None)
    >>> vocabulary.default_factory = vocabulary.__len__
    >>> j_indices = []
    >>> analyzed = ["foo", "bar", "baz", "foo", "quux"]
    >>> for feature in analyzed:
    ...     j = vocabulary[feature]
    ...     print("%s %d" % (feature, j))
    ...     j_indices.append(j)
    ...     
    foo 0
    bar 1
    baz 2
    foo 0
    quux 3
    

    结果

    >>> dict(vocabulary)
    {'bar': 1, 'foo': 0, 'baz': 2, 'quux': 3}
    >>> j_indices
    [0, 1, 2, 0, 3]
    

    所以这段代码可以正常工作。 KeyError 捕捉是针对fixed_vocab=True 的情况。

    【讨论】:

    • 感谢您的帮助——尤其是示例代码。现在我对 deafultdict 在做什么有了更好的了解。我刚刚阅读了一些内容,并意识到如果在字典中找不到新词汇项,它会将新词汇项附加到字典对象中。
    • 我无法理解这一行:词汇表.default_factory = 词汇表.__len__。我阅读了 docs.python.org 上的文档,但我不明白 len 在做什么以及这条线如何提供帮助。感谢您的帮助!
    • @SammyLee:默认工厂是在defaultdict 中没有密钥时调用的函数。在这种情况下,它会调用自己的__len__ 实现,因此每个看不见的键都会得到一个比前一个多一个的值。
    猜你喜欢
    • 2021-01-25
    • 2020-08-17
    • 2013-11-04
    • 2015-02-26
    • 2014-07-23
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多