Python 使用自定义词汇表进行TfidfVectorizer scikit学习时遇到的问题

Python 使用自定义词汇表进行TfidfVectorizer scikit学习时遇到的问题,python,scikit-learn,tf-idf,vocabulary,Python,Scikit Learn,Tf Idf,Vocabulary,我试图在scikit learn中使用自定义词汇表来完成一些集群任务,结果非常奇怪 当不使用自定义词汇表时,程序运行正常,我对集群的创建感到满意。但是,我已经确定了一组我想用作自定义词汇表的单词(大约24000个) 这些单词存储在SQL Server表中。到目前为止,我已经尝试了两种方法,但最终得到了相同的结果。第一个是创建列表,第二个是创建字典。创建字典的代码如下所示: myvocab = {} vocabulary = [] count = 0 for row in results:

我试图在scikit learn中使用自定义词汇表来完成一些集群任务,结果非常奇怪

当不使用自定义词汇表时,程序运行正常,我对集群的创建感到满意。但是,我已经确定了一组我想用作自定义词汇表的单词(大约24000个)

这些单词存储在SQL Server表中。到目前为止,我已经尝试了两种方法,但最终得到了相同的结果。第一个是创建列表,第二个是创建字典。创建字典的代码如下所示:

myvocab = {}
vocabulary = []

count = 0

for row in results:
    skillName = re.sub(r'&#?[a-z0-9]+;', ' ', row['SkillName']) 
    skillName = unicode(skillName,"utf-8")  
    vocabulary.append(skillName)  #Using a list 
    myvocab[str(skillName)] = count #Using a dictionary
    count+=1
然后,我在TfidfVectorizer中使用词汇表(列表版本或字典,两者在最后给出相同的结果),如下所示:

vectorizer = TfidfVectorizer(max_df=0.8, 
                         stop_words='english' ,ngram_range=(1,2) ,vocabulary=myvocab)
X = vectorizer.fit_transform(dataset2)
X的形状是(65124321),因为我有651个实例要聚类,词汇表中有24321个单词

如果我打印X的内容,我得到的是:

(14, 11462) 1.0
(20, 10218) 1.0
(34, 11462) 1.0
(40, 11462) 0.852815313278
(40, 10218) 0.52221264006
(50, 11462) 1.0
(81, 11462) 1.0
(84, 11462) 1.0
(85, 11462) 1.0
(99, 10218) 1.0
(127, 11462)    1.0
(129, 10218)    1.0
(132, 11462)    1.0
(136, 11462)    1.0
(138, 11462)    1.0
(150, 11462)    1.0
(158, 11462)    1.0
(186, 11462)    1.0
(210, 11462)    1.0

:   :
可以看出,对于大多数实例,只有词汇表中的单词存在(这是错误的,因为至少有10个),而对于许多实例,甚至没有找到一个单词。此外,在不同的实例中发现的单词往往是相同的,这是没有意义的

如果我使用以下方式打印功能名称:

feature_names = np.asarray(vectorizer.get_feature_names())
我得到:

['.NET' '10K' '21 CFR Part 11' ..., 'Zend Studio' 'Zendesk' 'Zenworks']
我必须说,当所使用的词汇表是由输入文档确定的词汇表时,程序运行得很好,因此我强烈怀疑问题与使用自定义词汇表有关

有人知道发生了什么事吗


(我没有使用管道,所以这个问题不可能与之前已经修复的错误有关)

让我感到不寻常的一件事是,在创建矢量器时,您指定了
ngram\u range=(1,2)
。这意味着您无法使用标准标记器获取功能
'21 CFR Part 11'
。我怀疑,
n>2
的“缺失”功能是n-gram。您预先选择的词汇项目中有多少是单字或双字

我很确定这是由默认值
min_df=2
造成的(可以说是令人困惑的),如果数据集中没有出现至少两次,就从词汇表中删除任何特征。请您在代码中显式设置
min_df=1
以进行确认好吗?

在Python for in循环中,它不能使用count+=1使count在每次循环时添加一个。可以使用范围(n)中的i替换它。因为count的值将保持为1。

我将该值更改为min_df=1,结果完全相同。如果我打印TdidfVectorizer,这就是我得到的:TfidfVectorizer(analyzer=word,binary=False,charset=utf-8,charset\u error=strict,dtype=,input=content,lowercase=True,max\u df=0.8,max\u features=None,max\u n=None,min\u df=1,min\u n=None,ngram\u range=(1,2),norm=l2,preprocessor=None,smooth\u idf=True,stop\u words=english,strip\u accents=None,sublinear\u tf=False,token\u pattern=(?u)\b\w\w+\b,tokenizer=None,use\u idf=True,词汇=None),那么您的
dataset2
可能不是
tfidfvectorier
所期望的?检查
TFIDFvectorier
文档中的
input
参数。您可以通过
TfidfVectorizer(**params).build_analyzer()(dataset2)
检查文本分析步骤的结果(预处理、标记化+n-grams提取)。我已经广泛使用该数据集进行分类和聚类,但现在我正试图使用自己的词汇表,这正是我遇到问题的时候。尽管如此,我还是会按照你的建议去做,并报告结果。我曾尝试使用(1,1)到(1,5)范围内ngram_的不同变体,我总是得到相同的结果。1克词汇项目的数量为9692个,2克:13215个,3克:1337个,4克:77个。我认为这不是问题所在。