【问题标题】:Convert a list of words to a list of integers in scikit-learn在 scikit-learn 中将单词列表转换为整数列表
【发布时间】:2015-08-25 02:12:46
【问题描述】:

我想在 scikit-learn 中将单词列表转换为整数列表,并为包含单词列表列表的语料库执行此操作。例如。语料库可以是一堆句子。

我可以使用sklearn.feature_extraction.text.CountVectorizer 执行以下操作,但有没有更简单的方法?我怀疑我可能缺少一些 CountVectorizer 功能,因为它是自然语言处理中常见的预处理步骤。在这段代码中,我首先拟合 CountVectorizer,然后我必须遍历每个单词列表的每个单词以生成整数列表。

import sklearn
import sklearn.feature_extraction
import numpy as np

def reverse_dictionary(dict):
    '''
    http://stackoverflow.com/questions/483666/python-reverse-inverse-a-mapping
    '''
    return {v: k for k, v in dict.items()}

vectorizer = sklearn.feature_extraction.text.CountVectorizer(min_df=1)

corpus = ['This is the first document.',
        'This is the second second document.',
        'And the third one.',
        'Is this the first document? This is right.',]

X = vectorizer.fit_transform(corpus).toarray()

tokenizer = vectorizer.build_tokenizer()
output_corpus = []
for line in corpus: 
    line = tokenizer(line.lower())
    output_line = np.empty_like(line, dtype=np.int)
    for token_number, token in np.ndenumerate(line):
        output_line[token_number] = vectorizer.vocabulary_.get(token) 
    output_corpus.append(output_line)
print('output_corpus: {0}'.format(output_corpus))

word2idx = vectorizer.vocabulary_
print('word2idx: {0}'.format(word2idx))

idx2word = reverse_dictionary(word2idx)
print('idx2word: {0}'.format(idx2word))

输出:

output_corpus: [array([9, 3, 7, 2, 1]), # 'This is the first document.'
                array([9, 3, 7, 6, 6, 1]), # 'This is the second second document.'
                array([0, 7, 8, 4]), # 'And the third one.'
                array([3, 9, 7, 2, 1, 9, 3, 5])] # 'Is this the first document? This is right.'
word2idx: {u'and': 0, u'right': 5, u'third': 8, u'this': 9, u'is': 3, u'one': 4,
           u'second': 6, u'the': 7, u'document': 1, u'first': 2}
idx2word: {0: u'and', 1: u'document', 2: u'first', 3: u'is', 4: u'one', 5: u'right', 
           6: u'second', 7: u'the', 8: u'third', 9: u'this'}

【问题讨论】:

    标签: python nlp scikit-learn


    【解决方案1】:

    我不知道是否有更直接的方法,但是您可以通过使用map 而不是 for-loop 来迭代每个单词来简化语法。

    您可以使用build_analyzer(),它同时处理预处理和标记化,然后无需显式调用lower()

    analyzer = vectorizer.build_analyzer()
    output_corpus = [map(lambda x: vectorizer.vocabulary_.get(x), analyzer(line)) for line in corpus]
    # For Python 3.x it should be
    # [list(map(lambda x: vectorizer.vocabulary_.get(x), analyzer(line))) for line in corpus]
    

    输出语料库:

    [[9, 3, 7, 2, 1], [9, 3, 7, 6, 6, 1], [0, 7, 8, 4], [3, 9, 7, 2, 1, 9, 3, 5]]
    

    编辑

    感谢@user3914041,在这种情况下,只使用列表理解可能更可取。它避免了lambda,因此可以略快于map。 (根据Python List Comprehension Vs. Map 和我的简单测试。)

    output_corpus = [[vectorizer.vocabulary_.get(x) for x in analyzer(line)] for line in corpus]
    

    【讨论】:

    • 我认为没有比这更好的了,我不知道使用CountVectorizer 的方法。我更喜欢列表理解语法:[[vectorizer.vocabulary_.get(x) for x in analyzer(line)] for line in corpus]
    • @user3914041Hmm... 我同意在这种情况下列表理解更可取
    【解决方案2】:

    我在python中经常使用Counter来解决这个问题,例如

    from collections import Counter
    
    corpus = ['This is the first document.',
            'This is the second second document.',
            'And the third one.',
            'Is this the first document? This is right.',]
    ​
    #convert to str from list and split
    as_one = ''
    for sentence in corpus:
        as_one = as_one + ' ' + sentence
    
    words = as_one.split()
    ​
    from collections import Counter
    counts = Counter(words)
    vocab = sorted(counts, key=counts.get, reverse=True)
    vocab_to_int = {word: ii for ii, word in enumerate(vocab, 1)}
    ​
    print(vocab_to_int)
    

    输出:

    {'the': 1, 'This': 2, 'is': 3, 'first': 4, 'document.': 5, 'second': 6、“和”:7、“第三”:8、“一”:9、“是”:10、“本”:11、“文件?”: 12,“正确。”:13}

    【讨论】:

    • 将 List 转换为 String 的更好方法可能是:as_one = ' '.join(corpus)
    【解决方案3】:

    对于给定的文本,CountVectorizer 旨在返回一个向量,该向量是每个单词的计数。

    例如对于语料库: corpus = ["the cat", "the dog"],向量器会找到 3 个不同的词,因此它将输出维度为 3 的向量,其中“the”对应于第一个维度,“cat”对应于第二个维度,“dog”对应于第三个维度。例如,“the cat”会转换为 [1, 1, 0],“the dog” 会转换为 [1, 0, 1],重复单词的句子会有更大的值(例如“the cat cat” → [ 1, 2, 0])。

    对于您想要的,您会很高兴使用Zeugma 包。您只需执行以下操作(在终端中运行 pip install zeugma 之后):

    >>> from zeugma import TextsToSequences
    >>> sequencer = TextsToSequences()
    >>> sequencer.fit_transform(["this is a sentence.", "and another one."])
    array([[1, 2, 3, 4], [5, 6, 7]], dtype=object)
    

    而且你总是可以访问“索引到单词的映射:with

    >>> sequencer.index_word
    {1: 'this', 2: 'is', 3: 'a', 4: 'sentence', 5: 'and', 6: 'another', 7: 'one'}
    

    从那里您可以使用此映射转换任何新句子:

    >>> sequencer.transform(["a sentence"])
    array([[3, 4]])
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2015-06-02
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 2017-11-28
      • 2016-12-16
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多