【问题标题】:Restore original text from Keras’s imdb dataset从 Keras 的 imdb 数据集中恢复原始文本
【发布时间】:2017-08-06 20:59:51
【问题描述】:

从 Keras 的 imdb 数据集中恢复原始文本

我想从 Keras 的 imdb 数据集中恢复 imdb 的原始文本。

首先,当我加载 Keras 的 imdb 数据集时,它返回了单词索引序列。

>>> (X_train, y_train), (X_test, y_test) = imdb.load_data()
>>> X_train[0]
[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 22665, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 21631, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 19193, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 10311, 8, 4, 107, 117, 5952, 15, 256, 4, 31050, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 12118, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]

我找到了 imdb.get_word_index 方法(),它返回单词索引字典,如 {‘create’: 984, ‘make’: 94,…}。为了进行转换,我创建了索引词词典。

>>> word_index = imdb.get_word_index()
>>> index_word = {v:k for k,v in word_index.items()}

然后,我尝试恢复原始文本,如下所示。

>>> ' '.join(index_word.get(w) for w in X_train[5])
"the effort still been that usually makes for of finished sucking ended cbc's an because before if just though something know novel female i i slowly lot of above freshened with connect in of script their that out end his deceptively i i"

我英语不好,但我知道这句话很奇怪。

为什么会这样?如何恢复原文?

【问题讨论】:

    标签: python machine-learning neural-network nlp keras


    【解决方案1】:

    你的例子是胡言乱语,它比仅仅缺少一些停用词要糟糕得多。

    如果您重新阅读 [keras.datasets.imdb.load_data](https://keras.io/datasets/#imdb-movie-reviews-sentiment-classificationstart_charoov_charindex_from 参数的文档 ) 方法他们解释发生了什么:

    start_char: 整数。序列的开始将用这个字符标记。设置为 1,因为 0 通常是填充字符。

    oov_char: 整数。由于 num_words 或 skip_top 限制而被删除的单词将替换为此字符。

    index_from: 整数。使用此索引或更高索引来索引实际单词。

    您反转的字典假定单词索引从 1 开始。

    但是返回我的 keras 的索引有 <START><UNKNOWN> 作为索引 12。 (并且假设您将使用0 代替<PADDING>)。

    这对我有用:

    import keras
    NUM_WORDS=1000 # only use top 1000 words
    INDEX_FROM=3   # word index offset
    
    train,test = keras.datasets.imdb.load_data(num_words=NUM_WORDS, index_from=INDEX_FROM)
    train_x,train_y = train
    test_x,test_y = test
    
    word_to_id = keras.datasets.imdb.get_word_index()
    word_to_id = {k:(v+INDEX_FROM) for k,v in word_to_id.items()}
    word_to_id["<PAD>"] = 0
    word_to_id["<START>"] = 1
    word_to_id["<UNK>"] = 2
    word_to_id["<UNUSED>"] = 3
    
    id_to_word = {value:key for key,value in word_to_id.items()}
    print(' '.join(id_to_word[id] for id in train_x[0] ))
    

    标点符号不见了,但仅此而已:

    "<START> this film was just brilliant casting <UNK> <UNK> story
     direction <UNK> really <UNK> the part they played and you could just
     imagine being there robert <UNK> is an amazing actor ..."
    

    【讨论】:

    • 文档中的什么地方这么说?我只发现这个“按照惯例,“0”不代表特定的单词,而是用来编码任何未知的单词。”
    • @RodrigoRuizkeras.io/datasets/#imdb-movie-reviews-sentiment-classification 的文档还提供了参数 start_char=1、oov_char=2、index_from=3 的默认值,这些值会导致此处描述的转换。如果你使用 start_char=0, oov_char=0, index_from=1,你会得到 0 的未知词。
    • 这段代码实际上是不正确的。一行应更改为word_to_id={k:(v+INDEX_FROM-1) for k,v in word_to_id.items()}。下载的word_to_id字典中的索引实际上是从1开始的。因此,当您将INDEX_FROM添加到索引时,会导致id_to_word[2]id_to_word[4]之间存在间隙。 id_to_word[3] 没有任何价值。
    • 同意最后的评论
    • 如果我们设置 index_from = 3 那么索引值为 1、2 的单词会发生什么变化。 index_from 实际上是做什么的?
    【解决方案2】:

    您可以使用 keras.utils.data_utils 中的 get_file 获取不移除停用词的原始数据集:

    path = get_file('imdb_full.pkl',
                   origin='https://s3.amazonaws.com/text-datasets/imdb_full.pkl',
                    md5_hash='d091312047c43cf9e4e38fef92437263')
    f = open(path, 'rb')
    (training_data, training_labels), (test_data, test_labels) = pickle.load(f)
    

    学分 - Jeremy Howards fast.ai course lesson 5

    【讨论】:

      【解决方案3】:

      这是因为基本的NLP 数据准备。大量所谓的停用词已从文本中删除,以使学习变得可行。通常——在预处理过程中,大部分的标点符号和不太常见的词也会从文本中删除。我认为恢复原始文本的唯一方法是使用例如在 IMDB 中找到最匹配的文本。 Google 的浏览器 API。

      【讨论】:

      • 这个答案是错误的。停用词没有被删除。只看mdaoust answer中的例句(没错),里面有“the”和“and”。
      【解决方案4】:

      此编码将与标签一起使用:

      from keras.datasets import imdb
      (x_train,y_train),(x_test,y_test) = imdb.load_data()
      word_index = imdb.get_word_index() # get {word : index}
      index_word = {v : k for k,v in word_index.items()} # get {index : word}
      
      index = 1
      print(" ".join([index_word[idx] for idx in x_train[index]]))
      print("positve" if y_train[index]==1 else "negetive")
      

      如果有帮助,请点赞。 :)

      【讨论】:

        【解决方案5】:

        索引偏移 3,因为 0、1 和 2 是“填充”、“序列开始”和“未知”的保留索引。以下应该可以工作。

        imdb = tf.keras.datasets.imdb
        (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
        
        word_index = imdb.get_word_index()
        reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
        
        review = [reverse_word_index.get(i-3, "?") for i in train_data[0]]
        

        【讨论】:

          【解决方案6】:

          这对我有用:

          word_index = imdb.get_word_index()                                    
          reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])            
          decoded_review = ' '.join([reverse_word_index.get(i - 3, "") for i in train_data[0]])
          

          【讨论】:

            【解决方案7】:

            要获得所有评论的等效数组:

            def decode_imdb_reviews(text_data):
                result = [0 for x in range(len(text_data))]
                word_index = imdb.get_word_index()
                reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
                for review in range(0,len(text_data)):
                    for index in enumerate(text_data[review]):
                        decoded_review = ' '.join([reverse_word_index.get(index - 3, '#') for index in text_data[review]])
                    result[review] = decoded_review
                return result
            
            text_data = []
            text_data = decode_imdb_reviews(train_data)
            

            【讨论】:

              【解决方案8】:

              试试下面的代码。此代码有效。

              # load dataset 
              from tensorflow.keras.datasets import imdb 
              (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=500)
              
              
              # vec 2 num 
              imdb_vec2num = imdb.get_word_index(path="imdb_word_index.json")
              # num 2 vec 
              imdb_num2vec = {value+3:key for key, value in imdb_vec2num.items()}
              imdb_num2vec[0] = "<PAD>"
              imdb_num2vec[1] = "<START>"
              imdb_num2vec[2] = "<UNK>"
              imdb_num2vec[3] = "<UNUSED>"
              
              # index-word table
              imdb_num2vec = {value:key for key, value in imdb_index.items()}
              
              # change encoded sentences to sentences
              def restore_sentences(num2word, encoded_sentences): 
                  sentences = []
                  for encoded_sentence in encoded_sentences:
                      sentences.append([num2word[ele] for ele in encoded_sentence])
                  return sentences
              
              # example 
              sentences = restore_sentences(imdb_num2vec, x_train)
              

              【讨论】:

                【解决方案9】:
                from keras.datasets import imdb
                NUM_WORDS=1000 # only use top 1000 words
                
                (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=NUM_WORDS)
                

                获取索引详细信息:

                word_to_id = keras.datasets.imdb.get_word_index()
                

                构建键值对:

                id_to_word = {value:key for key,value in word_to_id.items()}
                print(' '.join(id_to_word[id] for id in x_train[0] ))
                

                【讨论】:

                • 检查了这段代码,这就是我得到的:the as you with out themselves powerful and and their becomes and had and of lot from anyone to have after out atmosphere ...
                猜你喜欢
                • 2020-01-26
                • 2021-05-30
                • 1970-01-01
                • 1970-01-01
                • 2018-11-12
                • 2011-03-19
                • 2017-10-15
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多