首页 文章

理解文本特征提取python scikit-learn中的TfidfVectorizer

提问于
浏览
5

阅读scikit-learn中文本特征提取的文档,我不确定TfidfVectorizer(可能是其他矢量化器)可用的不同参数如何影响结果 .

以下是我不确定它们如何工作的论据:

TfidfVectorizer(stop_words='english',  ngram_range=(1, 2), max_df=0.5, min_df=20, use_idf=True)

文档清楚地说明了stop_words / max_df的使用(两者都有相似的效果,可以使用一个而不是另一个) . 但是,我不确定这些选项是否应与ngrams一起使用 . 首先出现/处理哪一个,ngrams或stop_words?为什么?根据我的实验,首先删除停用词,但是ngrams的目的是提取短语等 . 我不确定这个序列的效果(Stops删除然后ngramed) .

其次,将max_df / min_df参数与use_idf参数一起使用是否有意义?这些类似的目的不是?

2 回答

  • 10

    我在这篇文章中看到了几个问题 .

    TfidfVectorizer中的不同参数如何相互作用?

    你真的必须用它来培养一种直觉感(无论如何都是我的经验) .

    TfidfVectorizer是一个单词的方法 . 在NLP中,单词序列及其窗口很重要;这种破坏了一些背景 .

    How do I control what tokens get outputted?

    ngram_range 设置为(1,1)仅输出一个单词令牌,(1,2)表示单字和双字令牌,(2,3)表示双字和三字令牌等 .

    ngram_rangeanalyzer 携手合作 . 将 analyzer 设置为"word"以输出单词和短语,或将其设置为"char"以输出字符ngrams .

    如果您希望输出同时具有"word"和"char"功能,请使用sklearn的FeatureUnion . 示例here .

    How do I remove unwanted stuff?

    使用 stop_words 删除不太有意义的英语单词 .

    sklearn使用的停用词列表可在以下位置找到:

    from sklearn.feature_extraction.stop_words import ENGLISH_STOP_WORDS
    

    删除停用词的逻辑与这些词没有很多意义的事实有关,并且它们在大多数文本中都出现了很多:

    [('the', 79808),
     ('of', 40024),
     ('and', 38311),
     ('to', 28765),
     ('in', 22020),
     ('a', 21124),
     ('that', 12512),
     ('he', 12401),
     ('was', 11410),
     ('it', 10681),
     ('his', 10034),
     ('is', 9773),
     ('with', 9739),
     ('as', 8064),
     ('i', 7679),
     ('had', 7383),
     ('for', 6938),
     ('at', 6789),
     ('by', 6735),
     ('on', 6639)]
    

    由于停用词通常具有较高的频率,因此使用 max_df 作为0.95的浮点数来移除前5%可能是有意义的但是你很常见的是顶部的单词或短语不是停止词,因为我使用密集非常具体的主题中的文本(搜索查询数据) .

    使用 min_df 作为整数来删除罕见的单词 . 如果他们只出现一次或两次,他们通常会赢得很多,所以忽略它们,比如说 min_df=5 可以大大减少你的内存消耗和数据大小 .

    How do I Include stuff that's being stripped out?

    token_pattern 使用正则表达式模式 \b\w\w+\b ,这意味着令牌必须至少为2个字符,因此删除了像"I","a"这样的单词,并删除了0到9之类的数字 . 你还会注意到它删除了撇号

    首先发生什么,ngram生成或停止删除单词?

    我们来做一点测试吧 .

    import numpy as np
    import pandas as pd
    
    from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
    from sklearn.feature_extraction.stop_words import ENGLISH_STOP_WORDS
    
    docs = np.array(['what is tfidf',
            'what does tfidf stand for',
            'what is tfidf and what does it stand for',
            'tfidf is what',
            "why don't I use tfidf",
            '1 in 10 people use tfidf'])
    
    tfidf = TfidfVectorizer(use_idf=False, norm=None, ngram_range=(1, 1))
    matrix = tfidf.fit_transform(docs).toarray()
    
    df = pd.DataFrame(matrix, index=docs, columns=tfidf.get_feature_names())
    
    for doc in docs:
        print(' '.join(word for word in doc.split() if word not in ENGLISH_STOP_WORDS))
    

    打印出:

    tfidf
    does tfidf stand
    tfidf does stand
    tfidf
    don't I use tfidf
    1 10 people use tfidf
    

    现在让我们打印df:

    10  and  does  don  for   in   is  \
    what is tfidf                             0.0  0.0   0.0  0.0  0.0  0.0  1.0   
    what does tfidf stand for                 0.0  0.0   1.0  0.0  1.0  0.0  0.0   
    what is tfidf and what does it stand for  0.0  1.0   1.0  0.0  1.0  0.0  1.0   
    tfidf is what                             0.0  0.0   0.0  0.0  0.0  0.0  1.0   
    why don't I use tfidf                     0.0  0.0   0.0  1.0  0.0  0.0  0.0   
    1 in 10 people use tfidf                  1.0  0.0   0.0  0.0  0.0  1.0  0.0   
    
                                               it  people  stand  tfidf  use  \
    what is tfidf                             0.0     0.0    0.0    1.0  0.0   
    what does tfidf stand for                 0.0     0.0    1.0    1.0  0.0   
    what is tfidf and what does it stand for  1.0     0.0    1.0    1.0  0.0   
    tfidf is what                             0.0     0.0    0.0    1.0  0.0   
    why don't I use tfidf                     0.0     0.0    0.0    1.0  1.0   
    1 in 10 people use tfidf                  0.0     1.0    0.0    1.0  1.0   
    
                                              what  why  
    what is tfidf                              1.0  0.0  
    what does tfidf stand for                  1.0  0.0  
    what is tfidf and what does it stand for   2.0  0.0  
    tfidf is what                              1.0  0.0  
    why don't I use tfidf                      0.0  1.0  
    1 in 10 people use tfidf                   0.0  0.0
    

    笔记:

    • use_idf=False, norm=None 当这些设置完毕后,'s equivalent to using sklearn'的CountVectorizer . 它只会返回计数 .

    • 注意单词"don't"已转换为"don" . 这是你将 token_pattern 更改为 token_pattern=r"\b\w[\w']+\b" 以包含撇号的地方 .

    • 我们看到了很多停顿词

    让我们删除停用词并再次查看df:

    tfidf = TfidfVectorizer(use_idf=False, norm=None, stop_words='english', ngram_range=(1, 2))
    

    输出:

    10  10 people  does  does stand  \
    what is tfidf                             0.0        0.0   0.0         0.0   
    what does tfidf stand for                 0.0        0.0   1.0         0.0   
    what is tfidf and what does it stand for  0.0        0.0   1.0         1.0   
    tfidf is what                             0.0        0.0   0.0         0.0   
    why don't I use tfidf                     0.0        0.0   0.0         0.0   
    1 in 10 people use tfidf                  1.0        1.0   0.0         0.0   
    
                                              does tfidf  don  don use  people  \
    what is tfidf                                    0.0  0.0      0.0     0.0   
    what does tfidf stand for                        1.0  0.0      0.0     0.0   
    what is tfidf and what does it stand for         0.0  0.0      0.0     0.0   
    tfidf is what                                    0.0  0.0      0.0     0.0   
    why don't I use tfidf                            0.0  1.0      1.0     0.0   
    1 in 10 people use tfidf                         0.0  0.0      0.0     1.0   
    
                                              people use  stand  tfidf  \
    what is tfidf                                    0.0    0.0    1.0   
    what does tfidf stand for                        0.0    1.0    1.0   
    what is tfidf and what does it stand for         0.0    1.0    1.0   
    tfidf is what                                    0.0    0.0    1.0   
    why don't I use tfidf                            0.0    0.0    1.0   
    1 in 10 people use tfidf                         1.0    0.0    1.0   
    
                                              tfidf does  tfidf stand  use  \
    what is tfidf                                    0.0          0.0  0.0   
    what does tfidf stand for                        0.0          1.0  0.0   
    what is tfidf and what does it stand for         1.0          0.0  0.0   
    tfidf is what                                    0.0          0.0  0.0   
    why don't I use tfidf                            0.0          0.0  1.0   
    1 in 10 people use tfidf                         0.0          0.0  1.0   
    
                                              use tfidf  
    what is tfidf                                   0.0  
    what does tfidf stand for                       0.0  
    what is tfidf and what does it stand for        0.0  
    tfidf is what                                   0.0  
    why don't I use tfidf                           1.0  
    1 in 10 people use tfidf                        1.0
    

    外卖:

    • 令牌"don use"发生了因为 don't I use 剥离了 't 并因为 I 少于两个字符,所以它被删除所以单词被加入 don use ......这实际上不是结构,可能会改变结构!

    • Answer: stop words are removed, short characters are removed, then ngrams are generated which can return unexpected results.

    将max_df / min_df参数与use_idf参数一起使用是否有意义?

    我认为,术语 - 频率逆文档频率的整个要点是允许重新加权高频词(将出现在排序频率列表顶部的词) . 这种重新加权将采用最高频率的ngrams并将它们从列表中移到较低的位置 . 因此,它应该处理 max_df 场景 .

    也许更多的是个人选择是否要将它们移到列表中(“重新加权”/取消优先级)或完全删除它们 .

    我经常使用 min_df ,如果你增加 Value 而使用 min_df 是有意义的,这只会导致很多处理问题 . 我不太多使用 max_df 但是我确信在使用像维基百科这样的数据时有一些情况可能会删除顶部的x% .

  • 1
    • 删除停用词不会影响您的ngrams . 首先根据您的tokenizer和ngram范围创建词汇表(令牌)列表,然后从该列表中删除停用词(因此只有unigrams会受到影响,因为停用词列表仅包含ungrams) . 请注意,如果您在标记化步骤中删除了停用词(人们经常这样做),那么它们就不一样了,那么它们也不会被包含在双字母组中 .

    • 使用min_df实际上可以抵消tf idf的影响,因为在一个文档中可能出现两次的单词将具有高分(记住分数是针对文档的) . 这取决于您的系统的应用(信息检索/文本分类) . 如果阈值很低,它不应该影响很多文本分类,但检索可能有偏见(如果我想查找带有"Spain"的文档,并且它只在一个文档中出现一次,在整个集合中?) . 正如你所说的那样,由于use_idf,Max_df会受到影响,但是如果你从词汇表中删除这个词,那么它可能会比仅仅加权低得多 . 这又取决于你打算如何处理重量 .

    希望这可以帮助 .

相关问题