【问题标题】:Use sklearn TfidfVectorizer with already tokenized inputs?使用已标记化输入的 sklearn TfidfVectorizer?
【发布时间】:2018-07-18 04:24:45
【问题描述】:

我有一个标记化句子的列表,并且想安装一个 tfidf Vectorizer。我尝试了以下方法:

tokenized_list_of_sentences = [['this', 'is', 'one'], ['this', 'is', 'another']]

def identity_tokenizer(text):
  return text

tfidf = TfidfVectorizer(tokenizer=identity_tokenizer, stop_words='english')    
tfidf.fit_transform(tokenized_list_of_sentences)

错误输出为

AttributeError: 'list' object has no attribute 'lower'

有没有办法做到这一点?我有十亿个句子,不想再次标记它们。在此之前的另一个阶段,它们被标记化。

【问题讨论】:

  • 为了能够提供帮助,请添加完整的错误消息并添加重现错误所需的最少代码。

标签: scikit-learn tfidfvectorizer


【解决方案1】:

尝试使用参数lowercase=False 初始化TfidfVectorizer 对象(假设这是实际需要的,因为您在之前的阶段已将标记小写)。

tokenized_list_of_sentences = [['this', 'is', 'one', 'basketball'], ['this', 'is', 'a', 'football']]

def identity_tokenizer(text):
    return text

tfidf = TfidfVectorizer(tokenizer=identity_tokenizer, stop_words='english', lowercase=False)    
tfidf.fit_transform(tokenized_list_of_sentences)

请注意,我更改了句子,因为它们显然只包含停用词,由于词汇表为空而导致另一个错误。

【讨论】:

  • 关于如何保存和加载 TfidfVectorizer 对象的任何想法?如果我使用的是外部函数,例如本例中的函数?我在尝试加载它时遇到错误。
【解决方案2】:

就像@Jarad said 一样,只需为您的分析器使用“直通”功能,但它需要忽略停用词。你可以从sklearn获取停用词:

>>> from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS

或来自nltk

>>> import nltk
>>> nltk.download('stopwords')
>>> from nltk.corpus import stopwords
>>> stop_words = set(stopwords.words('english'))

或将两个集合组合起来:

stop_words = stop_words.union(ENGLISH_STOP_WORDS)

但是你的例子只包含停用词(因为你所有的词都在sklearn.ENGLISH_STOP_WORDS 集中)。

不过@Jarad 的例子很有效:

>>> tokenized_list_of_sentences =  [
...     ['this', 'is', 'one', 'cat', 'or', 'dog'],
...     ['this', 'is', 'another', 'dog']]
>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> tfidf = TfidfVectorizer(analyzer=lambda x:[w for w in x if w not in stop_words])
>>> tfidf_vectors = tfidf.fit_transform(tokenized_list_of_sentences)

我喜欢 pd.DataFrames 浏览 TF-IDF 向量:

>>> import pandas as pd
>>> pd.DataFrame(tfidf_vectors.todense(), columns=tfidf.vocabulary_)
        cat       dog 
0  0.814802  0.579739
1  0.000000  1.000000

【讨论】:

    【解决方案3】:

    尝试preprocessor 而不是tokenizer

        return lambda x: strip_accents(x.lower())
    AttributeError: 'list' object has no attribute 'lower'
    

    如果上述错误信息中的x是一个列表,那么对列表执行x.lower()会抛出错误。

    您的两个示例都是停用词,因此要使此示例返回某些内容,请输入一些随机词。这是一个例子:

    tokenized_sentences = [['this', 'is', 'one', 'cat', 'or', 'dog'],
                           ['this', 'is', 'another', 'dog']]
    
    tfidf = TfidfVectorizer(preprocessor=' '.join, stop_words='english')
    tfidf.fit_transform(tokenized_sentences)
    

    返回:

    <2x2 sparse matrix of type '<class 'numpy.float64'>'
        with 3 stored elements in Compressed Sparse Row format>
    

    特点:

    >>> tfidf.get_feature_names()
    ['cat', 'dog']
    

    更新:也许在标记器和预处理器上使用lambdas?

    tokenized_sentences = [['this', 'is', 'one', 'cat', 'or', 'dog'],
                           ['this', 'is', 'another', 'dog']]
    
    tfidf = TfidfVectorizer(tokenizer=lambda x: x,
                            preprocessor=lambda x: x, stop_words='english')
    tfidf.fit_transform(tokenized_sentences)
    
    <2x2 sparse matrix of type '<class 'numpy.float64'>'
        with 3 stored elements in Compressed Sparse Row format>
    >>> tfidf.get_feature_names()
    ['cat', 'dog']
    

    【讨论】:

    • 这会重新标记预处理器加入的输入。我不想再次花费资源重新标记。
    猜你喜欢
    • 2013-12-06
    • 1970-01-01
    • 2018-04-08
    • 2020-03-24
    • 2021-03-09
    • 2015-09-04
    • 1970-01-01
    • 2014-11-29
    • 2019-12-27
    相关资源
    最近更新 更多