【问题标题】:One-hot encode sentence using list of vocabulary使用词汇表的 One-hot 编码句子
【发布时间】:2020-11-15 11:19:12
【问题描述】:

我需要创建一个函数,该函数将字符串列表作为输入,每个字符串都是一本书内容的字符串。输出需要是一个 2D np 计数数组,其中行是输入字符串中的书籍,列是“全局词汇表”中所有单词的计数。因此,如果两个字符串是输入并且它们有 50 个唯一词,则矩阵的形状将是 (2,50)。

我有一个以前的代码,它获取一个字符串列表,并按照词典编纂者的顺序从字符串的唯一单词中创建一个字典,命名为我被允许使用的词汇,我只是不知道如何打开这个字典成一个矩阵。

这是我目前所拥有的,但它不起作用,因为“列表索引必须是整数或切片而不是 str”:

def feature(strings):

    import numpy as np

    array_dict = global_vocab(strings)
    i = 0
    for i in range(len(strings)):
        names = strings[i]
        matrix = np.array([array_dict[i] for i in names])
    
    print (matrix)

所以如果输入它 ["这是字符串一", "这是字符串二"] 该函数应该返回数组

1 1 1 1 0
1 1 1 0 1

我还使用了这些以前的代码:

def word_count(book):

    try:
        from collections import defaultdict
    
        file = book.lower().split()
        my_dict = defaultdict(int)
        for item in file:
            if len(item)>2:
                my_dict[item] += 1
            
        return my_dict
    
    except FileNotFoundError:
        return None

def global_vocab(strings):

    from collections import defaultdict

    my_dict = []
    i = 0
    for i in range(len(strings)):
        words = strings[i]
        sentences = word_count(words)
        my_dict.extend(sentences)

    return sorted(my_dict)

【问题讨论】:

  • 您能发布一个输入示例,以及输出应该是什么样子的示例吗?
  • 你不需要做 i = 0
  • 您的 global_vocabulary 返回什么类型的数据?也许你应该尝试像 array_dict = [*global_vocabulary(strings)] 或者去掉括号
  • @MattHowell 我添加了输入和输出的样子
  • @Kaiyaha global_vocabulary 返回字符串中所有唯一单词的字典,我不需要包含此函数我只是认为它会简化过程

标签: python numpy dictionary


【解决方案1】:

首先,将字符串处理成单词列表:

wordss = [s.split() for s in strings]

如果您有字典,则可以将它们映射到一些序数。在这里,我只是构建了自己的字典:

unique_words = set(word for words in wordss for word in words)
dictionary = {x: i for i, x in enumerate(unique_words)}

注意:如果您更喜欢“更好”的顺序,您可以改用这个:

unique_words = {word: 0 for words in wordss for word in words}
dictionary = {x: i for i, x in enumerate(unique_words)}

最后是one-hot编码:

idxss = [[dictionary[word] for word in words] for words in wordss]
embedding = np.zeros((len(idxss), len(dictionary)), dtype=np.uint8)

for i, idxs in enumerate(idxss):
    embedding[i, idxs] = 1

完整示例:

def embed(strings, dictionary=None):
    wordss = [s.split() for s in strings]
    
    if dictionary is None:
        unique_words = {word: 0 for words in wordss for word in words}
        dictionary = {x: i for i, x in enumerate(unique_words)}
    
    idxss = [[dictionary[word] for word in words] for words in wordss]
    embedding = np.zeros((len(idxss), len(dictionary)), dtype=np.uint8)

    for i, idxs in enumerate(idxss):
        embedding[i, idxs] = 1

    return embedding, dictionary
>>> strings = ["This is string one", "This is string two"]
... embedding, dictionary = embed(strings)

>>> dictionary
{'This': 0, 'is': 1, 'string': 2, 'one': 3, 'two': 4}

>>> embedding
array([[1, 1, 1, 1, 0],
       [1, 1, 1, 0, 1]], dtype=uint8)

【讨论】:

    【解决方案2】:

    稍微简化了你的代码。

    import numpy as np
    def feature(strings):
        from collections import Counter
        vocabulary = global_vocab(strings)
        print(vocabulary)
        matrix=[]
        for string in strings:
            word_count_string=Counter(string.lower().split())
            string_count=[]
            for word in vocabulary:
                string_count.append(word_count_string[word])
            matrix.append(string_count)
        for row in matrix:
            print(row)
        matrix=np.array(matrix)
        print(matrix.shape)
    
    # def word_count(book):
    #     from collections import Counter
    #     file = list(filter(lambda item: len(item)>2, book.lower().split()))
    #     my_dict = Counter(file)
    #     return my_dict
        
    def global_vocab(strings):
        total_vocabulary = set()
        for string in strings:
            total_vocabulary.update(list(filter(lambda item: len(item)>2, string.lower().split())))
        return sorted(list(total_vocabulary))
        # return list(total_vocabulary)
        
    feature(["This is string one", "This is string two"])
    

    输出:

    ['one', 'string', 'this', 'two']                                                                                        
    [1, 1, 1, 0]                                                                                                            
    [0, 1, 1, 1]                                                                                                            
    (2, 4)
    
                                                                                                            
    

    解释:

    global_vocab 返回所有字符串中唯一单词的列表,将其保存到一个名为词汇表的变量中,然后打印到屏幕上,以便在这里验证输出。

    现在,我们遍历strings 中的所有字符串,对于每个字符串,我们执行以下操作:

    1. 获取该字符串中单词的频率列表并将其存储到 word_count_string 变量。我们使用集合中的Counter 方法,该方法返回一个字典,其中键作为字符串中的唯一词,值作为该唯一词的频率。
    2. 此时,我们知道,这个字符串的每个唯一词在这个字符串中出现了多少次。现在我们想要这个字符串中词汇表中所有单词的频率。
    3. 我们初始化一个数组名称string_count,它将存储我们所需的词频。
    4. 现在我们检查vocabulary 中的所有单词,并将每个单词的计数附加到string_count。我们使用word_count_string 字典来获取此字符串中该单词的计数。请记住,word_count_string 已经使用 Counter 进行了计算。
    5. 最后,我们将string_count 追加到matrix 作为新行。

    编辑: 将 2d 列表矩阵转换为 NumPy 数组,现在您可以执行 matrix.shape 还有一件事,这次我还让global_vocab返回一个排序列表。

    【讨论】:

    • 我收到错误“'list' object has no attribute 'shape'”你知道为什么会发生这种情况吗?
    • 我的代码中特征函数中的矩阵是一个二维列表,列表确实有任何称为形状的属性。您可能正在做 matrix.shape 但这里的矩阵是一个二维列表而不是一个 numpy 数组。您可以在特征函数末尾使用 matrix = np.array(matrix) 轻松地将其转换为 numpy 数组。我将这个更改合并到我的代码中。如果您觉得代码符合您的要求,请为答案投票。
    猜你喜欢
    • 2020-09-18
    • 2019-06-28
    • 2021-02-16
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 2019-07-14
    • 2019-11-18
    相关资源
    最近更新 更多