ong*_*enz 9 python sparse-matrix tf-idf scikit-learn text-classification
我正在使用 TFIDF 稀疏矩阵进行文档分类,并且希望仅保留每个文档的前 n 个(比如 50 个)术语(按 TFIDF 分数排名)。请参阅下面的编辑。
import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
tfidfvectorizer = TfidfVectorizer(analyzer='word', stop_words='english',
token_pattern='[A-Za-z][\w\-]*', max_df=0.25)
n = 50
df = pd.read_pickle('my_df.pickle')
df_t = tfidfvectorizer.fit_transform(df['text'])
df_t
Out[15]:
<21175x201380 sparse matrix of type '<class 'numpy.float64'>'
with 6055621 stored elements in Compressed Sparse Row format>
Run Code Online (Sandbox Code Playgroud)
我已经尝试按照这篇文章中的示例进行操作,虽然我的目的不是显示特征,而是在训练前为每个文档选择前 n 个。但是我收到内存错误,因为我的数据太大而无法转换为密集矩阵。
df_t_sorted = np.argsort(df_t.toarray()).flatten()[::1][n]
Traceback (most recent call last):
File "<ipython-input-16-e0a74c393ca5>", line 1, in <module>
df_t_sorted = np.argsort(df_t.toarray()).flatten()[::1][n]
File "C:\Users\Me\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\sparse\compressed.py", line 943, in toarray
out = self._process_toarray_args(order, out)
File "C:\Users\Me\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\sparse\base.py", line 1130, in _process_toarray_args
return np.zeros(self.shape, dtype=self.dtype, order=order)
MemoryError
Run Code Online (Sandbox Code Playgroud)
有没有什么办法可以在不使用密集表示(即没有toarray()调用)并且没有比我已经拥有的(使用 min_df)减少太多特征空间的情况下做我想做的事?
注意:该max_features参数不是我想要的,因为它只考虑“按语料库中的词频排序的最高 max_features ”(此处的文档),而我想要的是文档级排名。
编辑:我想知道解决这个问题的最佳方法是否是将除n-best之外的所有特征的值设置为零。我这样说是因为已经计算了词汇表,因此特征索引必须保持不变,因为我想将它们用于其他目的(例如,可视化与n 个最佳特征对应的实际单词)。
一位同事编写了一些代码来检索排名最高的n个特征的索引:
n = 2
tops = np.zeros((df_t.shape[0], n), dtype=int) # store the top indices in a new array
for ind in range(df_t.shape[0]):
tops[ind,] = np.argsort(-df_t[ind].toarray())[0, 0:n] # for each row (i.e. document) sort the (inversed, as argsort is ascending) list and slice top n
Run Code Online (Sandbox Code Playgroud)
但从那里,我需要:
df_t) 并将所有值设置为 0,除了 中的n 个最佳索引tops。有一个帖子在这里解释如何使用csr_matrix工作,但我不知道如何付诸实践,这得到我想要的。
from nltk.tokenize import word_tokenize
from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer(tokenizer=word_tokenize,ngram_range=(1,2), binary=True, max_features=50)
TFIDF=vect.fit_transform(df['processed_cv_data'])
Run Code Online (Sandbox Code Playgroud)
该max_features参数传递TfidfVectorizer将挑选出排名前50位的特点下令他们的词频而不是由他们的TF-IDF得分。您可以使用以下方法查看功能:
print(vect.get_feature_names())
Run Code Online (Sandbox Code Playgroud)
正如您所提到的,max_featuresTfidfVectorizer 的参数是选择特征的一种方式。
如果您正在寻找一种考虑与目标变量的关系的替代方法,您可以使用 sklearn 的SelectKBest。通过设置k=50,这将过滤您的数据以获得最佳功能。用于选择的度量可以指定为参数score_func。
例子:
from sklearn.feature_selection import SelectKBest
tfidfvectorizer = TfidfVectorizer(analyzer='word', stop_words='english',
token_pattern='[A-Za-z][\w\-]*', max_df=0.25)
df_t = tfidfvectorizer.fit_transform(df['text'])
df_t_reduced = SelectKBest(k=50).fit_transform(df_t, df['target'])
Run Code Online (Sandbox Code Playgroud)
您还可以将其链接到管道中:
pipeline = Pipeline([("vectorizer", TfidfVectorizer()),
("feature_reduction", SelectKBest(k=50)),
("classifier", classifier)])
Run Code Online (Sandbox Code Playgroud)