我对CountVectorizer和TfidfVectorizer有疑问。
我不清楚如何在max_features中以相同的频率选择ngrams。如果我们在边界上具有相同频率的语料库中说max_features = 10000和100 ngrams,那么CountVectorizer如何分离ngram在特征中的含义以及哪些不是?玩具的例子,我们有一个包含八个独特单词的语料库。单词“jeans”和“cat”具有相同的freq 1.我们采用max_features = 7。为什么“猫”出现在功能和“牛仔裤”不是,但反之亦然?
data = ['gpu processor cpu performance',
'gpu performance ram computer computer',
'cpu computer ram processor jeans processor cat']
cv = CountVectorizer(ngram_range=(1, 1), max_features=7)
cv_fit = cv.fit_transform(data).toarray()
cv.vocabulary_
out:
{'cat': 0,
'computer': 1,
'cpu': 2,
'gpu': 3,
'performance': 4,
'processor': 5,
'ram': 6}
答案 0 :(得分:3)
这是link to the relevant source code _limit_features
辅助方法:
# Calculate a mask based on document frequencies
dfs = _document_frequency(X)
tfs = np.asarray(X.sum(axis=0)).ravel()
mask = np.ones(len(dfs), dtype=bool)
if high is not None:
mask &= dfs <= high
if low is not None:
mask &= dfs >= low
if limit is not None and mask.sum() > limit:
mask_inds = (-tfs[mask]).argsort()[:limit]
new_mask = np.zeros(len(dfs), dtype=bool)
new_mask[np.where(mask)[0][mask_inds]] = True
mask = new_mask
new_indices = np.cumsum(mask) - 1 # maps old indices to new
removed_terms = set()
for term, old_index in list(six.iteritems(vocabulary)):
if mask[old_index]:
vocabulary[term] = new_indices[old_index]
else:
del vocabulary[term]
removed_terms.add(term)
kept_indices = np.where(mask)[0]
注意,limit
是此辅助方法的参数,它传递的值为self.max_features
。因此,正如您所看到的,计算了一系列术语频率:
tfs = np.asarray(X.sum(axis=0)).ravel()
代码本质上是基于文档频率值构建一个布尔掩码(由max_df
和min_df
值控制)。然后,要仅将掩码限制为高于limit
的值,它会:
mask_inds = (-tfs[mask]).argsort()[:limit]
本质上返回使用limit
切片切成[:limit]
长度的term-frequency数组的排序索引。由于.argsort
默认使用快速排序算法,因此排序不稳定,因此,我相信您无法对保留哪些术语做出很多保证频率相等。无论快速排序发生在什么地方。如果使用了稳定的排序算法(在这种情况下,唯一的一种是合并排序),那么从the vocabulary is first sorted before the _limit_features
helper function is called开始:
if not self.fixed_vocabulary_:
X = self._sort_features(X, vocabulary)
n_doc = X.shape[0]
max_doc_count = (max_df
if isinstance(max_df, numbers.Integral)
else max_df * n_doc)
min_doc_count = (min_df
if isinstance(min_df, numbers.Integral)
else min_df * n_doc)
if max_doc_count < min_doc_count:
raise ValueError(
"max_df corresponds to < documents than min_df")
X, self.stop_words_ = self._limit_features(X, vocabulary,
max_doc_count,
min_doc_count,
max_features)
因此,词汇表将按字典顺序排序。因此,如果假设argsort使用稳定的算法,我相信我们可以说按字典顺序最高的术语会被保留,但是,由于它不稳定,我们无法做出这样的保证。
答案 1 :(得分:3)
CountVectorizer会切断术语频率,可能会使用普通排序来剪切max_features的项目。
max_features:int或None,默认=无如果不是None,则构建一个 只考虑按术语排序的最高max_features的词汇表 语料库中的频率。
我将数据从cat
更改为zat
,现在jeans
将数据转到列表中。
>>> data = ['gpu processor cpu performance',
'gpu performance ram computer computer',
'cpu computer ram processor zat processor jeans']
>>> cv = CountVectorizer(ngram_range=(1, 1), max_features=7)
>>> cv_fit = cv.fit_transform(data).toarray()
>>> cv.vocabulary_
{u'ram': 6, u'jeans': 3, u'processor': 5, u'computer': 0, u'performance': 4, u'gpu': 2, u'cpu': 1}
本质上它取决于排序顺序。