在scikit-learn中使用自定义词汇的TfidfVectorizer问题
我正在尝试在scikit-learn中使用自定义词汇来进行一些聚类任务,但结果非常奇怪。
当我不使用自定义词汇时,程序运行得很好,我对聚类的结果也很满意。不过,我已经找到了大约24,000个我想用作自定义词汇的单词。
这些单词存储在一个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的形状是(651, 24321),因为我有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']
我必须说,当使用从输入文档中确定的词汇时,程序运行得非常顺利,所以我强烈怀疑问题出在使用自定义词汇上。
有没有人知道发生了什么事?
(我没有使用管道,所以这个问题不可能与之前已经修复的错误有关)
3 个回答
在Python的for-in循环中,不能用count+=1来让count在每次循环时加一。你可以用for i in range(n):来替代它。因为这样count的值会一直保持为1。
我觉得这个问题是因为默认设置的 min_df=2
造成的,这个设置有点让人困惑。它的意思是,如果某个特征在数据集中出现的次数少于两次,就会被排除在词汇表之外。你能不能在你的代码里把这个设置改成 min_df=1
来确认一下呢?
有一点让我觉得很奇怪,就是当你创建向量化器时,你指定了 ngram_range=(1,2)
。这意味着你不能通过标准的分词器得到特征 '21 CFR Part 11'
。我猜那些“缺失”的特征是指长度大于2的n-grams。你预先选择的词汇中,有多少是单个词(unigrams)或两个词组合(bigrams)呢?