如何在scikit中计算术语频率 - 学习CountVectorizer

nik*_*osd 3 python tf-idf scikit-learn

我不明白CountVectorizer如何计算术语频率.我需要知道这一点,以便在max_df从语料库中过滤掉术语时,我可以为参数做出明智的选择.这是示例代码:

    import pandas as pd
    import numpy as np
    from sklearn.feature_extraction.text import CountVectorizer

    vectorizer = CountVectorizer(min_df = 1, max_df = 0.9)
    X = vectorizer.fit_transform(['afr bdf dssd','afr bdf c','afr'])
    word_freq_df = pd.DataFrame({'term': vectorizer.get_feature_names(), 'occurrences':np.asarray(X.sum(axis=0)).ravel().tolist()})
    word_freq_df['frequency'] = word_freq_df['occurrences']/np.sum(word_freq_df['occurrences'])
    print word_freq_df.sort('occurrences',ascending = False).head()

       occurrences  term  frequency
    0            3   afr   0.500000
    1            2   bdf   0.333333
    2            1  dssd   0.166667
Run Code Online (Sandbox Code Playgroud)

似乎'afr'出现在我的语料库中的一半术语中,正如我期望通过查看语料库.然而,当我max_df = 0.8进入时CountVectorizer,术语'afr'被从我的语料库中过滤掉.到处玩,我发现在我的例子中使用coprus,CountVectorizer为'afr'分配了一个~0.833的频率.有人可以提供一个关于如何max_df计算enterts的术语频率的公式吗?

谢谢

Bre*_*arn 5

问题显然不在于如何计算频率,而在于如何max_df应用阈值.代码CountVectorizer执行此操作:

max_doc_count = (max_df
    if isinstance(max_df, numbers.Integral)
    else int(round(max_df * n_doc))
)
Run Code Online (Sandbox Code Playgroud)

也就是说,通过将文档比例四舍五入到文档的数量来获得最大文档计数.这意味着,在3文档语料库中,任何max_df等于超过2.5个文档的阈值实际上与3个文档的阈值相同.您看到"频率"为2.5/3 = 0.8333 ---也就是说,在3个文档中约有83.3%出现的术语出现在其中的2.5个中,它被四舍五入为3,这意味着它出现在所有这些文档中.

简而言之,"afr"被正确地认为具有3的文档频率,但是最大文档频率被错误地认为是3(0.9*3 = 2.7,向上舍入到3).

我认为这是scikit中的一个错误.最大文档频率要圆下来,不涨.如果阈值为0.9,则所有文档中出现的术语都超过阈值,应排除.